Why does an API requested via the browser, get "304 Not Modified" ?

Not applicable

Hi,

I was following steps to add conditional flow as said in "Apigee - 4MV4D - API Proxy Flows - S01E06" and it works fine when I am trying using trace session and I am getting Response Sent to Client is 200 Ok but when I am accessing it from browser I am getting Response Sent to Client 304 Not Modified. Am I missing something here?

Thanks,

Barun

Solved Solved
0 8 3,565
1 ACCEPTED SOLUTION

Maybe? Let's talk about the "304 Not Modified" response.

See here for some good information. Here's my elaboration of the information there:

304 Not Modified is an HTTP response status code that the server returns to the client, to inform the client that the cached copy the client holds of a particular resource is the same content as is held by the server.

When a client such as a browser requests a resource (like a file or an API response) by sending a GET request to a server, the server can respond with the content for that resource as well as, optionally, a Last-Modified header that asserts a time (eg, Thursday, January 10th, at 13:04) the content was last modified. The client can then store the content in a cache, along with the value of the Last-Modified header sent from the server.

If the same client requests the same resource (as when a user reloads a web page), the client can include in its GET request an If-Modified-Since header, containing the value sent back previously in the last-modified header. Basically the client is saying to the server: "I have the content from "Thursday, January 10th, at 13:04", is there anything more recent? The server can reply to such a request with a 304 Not Modified header to tell the client "you have the most recent content." This allows the server to avoid sending the full content of the response, which can be large. The browser or client receiving this message can safely use cached content.

When you use a browser to send API requests, the browser implicitly sends the If-Modified-Since header, and implicitly and automatically manages the cache. If you use the "Send" button in the Trace UI, it does not send the if-modified-since header, and it does not handle the last-modified header. So no cache comes into play. The same would be true if you were to use Postman or curl or some other HTTP Rest client.

If you were interested, you could play around with including or excluding the if-modified-since header by using one of those other rest clients. For example, you can try this one, which allows you to send specific headers in each request.

View solution in original post

8 REPLIES 8

Maybe? Let's talk about the "304 Not Modified" response.

See here for some good information. Here's my elaboration of the information there:

304 Not Modified is an HTTP response status code that the server returns to the client, to inform the client that the cached copy the client holds of a particular resource is the same content as is held by the server.

When a client such as a browser requests a resource (like a file or an API response) by sending a GET request to a server, the server can respond with the content for that resource as well as, optionally, a Last-Modified header that asserts a time (eg, Thursday, January 10th, at 13:04) the content was last modified. The client can then store the content in a cache, along with the value of the Last-Modified header sent from the server.

If the same client requests the same resource (as when a user reloads a web page), the client can include in its GET request an If-Modified-Since header, containing the value sent back previously in the last-modified header. Basically the client is saying to the server: "I have the content from "Thursday, January 10th, at 13:04", is there anything more recent? The server can reply to such a request with a 304 Not Modified header to tell the client "you have the most recent content." This allows the server to avoid sending the full content of the response, which can be large. The browser or client receiving this message can safely use cached content.

When you use a browser to send API requests, the browser implicitly sends the If-Modified-Since header, and implicitly and automatically manages the cache. If you use the "Send" button in the Trace UI, it does not send the if-modified-since header, and it does not handle the last-modified header. So no cache comes into play. The same would be true if you were to use Postman or curl or some other HTTP Rest client.

If you were interested, you could play around with including or excluding the if-modified-since header by using one of those other rest clients. For example, you can try this one, which allows you to send specific headers in each request.

@Dino-at-Google how to avoid this on Apigee?

Help me out here. Did you try excluding the if-modified-since header? Did it work?

I am going to do that and let you know but do we really have to change things on Apigee Edge? can't we make some changes on server to avoid this?

on which server? I'm not clear.

When you use a browser to send API requests, the browser implicitly sends the If-Modified-Since header, and implicitly and automatically manages the cache. IF the backend (upstream?) server handles the "if-modified-since" header, then it MAY return a 304 Not Modified. Which means the browser will ... presumably fetch the content from cache and everything is good.

You want to short circuit that. So you either have to

  1. prevent the browser from sending if-modified-since. (Not gonna happen)
  2. intercept the call and eliminate that header via the apigee edge proxy. (I told you how to do this)
  3. modify the backend (upstream) server to not ever return 304.

If you don't want to allow clients to ever see 304's, then you need to pursue one of those options , I think.

thanks, @Dino-at-Google this is a detailed answer and I used 2 option and it worked for me.

Hi,

Can you please let me know how did you achieve this using option2. The link in this note is not working.

To restrict caching in the request, then....in the request flow, attach an AssignMessage like this:

<AssignMessage name='AM-PreventCaching'>
  <Remove>
    <Headers>
      <Header name='If-modified-since'/>
    </Headers>
  </Remove>
</AssignMessage>

Or, to modify the response so that it won't be cached, attach this in the response flow:

<AssignMessage name='AM-PreventCaching'>
  <Set>
    <Headers>
      <Header name='Cache-Control'>no-cache</Header>
    </Headers>
  </Set>
</AssignMessage>

But be careful, you probably don't want to do this, or don't need to do this.