Users who are just getting started with Fiddler are often confused about the appearance of HTTP/304 responses in Fiddler’s Web Sessions list as webpages are loaded:
A web server sends a HTTP/304 in response to a Conditional Validation request, indicating that the client’s copy of a resource is still valid and that the resource in question was Not Modified since the client cached its copy. Conditional validation enables clients to ensure that they have the latest resources without the performance overhead of the server re-sending all of its resources every time they are used.
Identifying Conditional Requests
A browser client sends a Conditional Validation request when it has a cached copy of a target resource but isn’t sure if that cached resource is the latest version. You can identify conditional requests in Fiddler by looking at the headers using the Headers Inspector.
When making a conditional request, the client provides the server the Last-Modified date of its copy using the If-Modified-Since header, and provides the cached copy’s ETag identifier using the If-None-Match header:
The server evaluates these headers to determine whether the client’s copy is the latest—if so, it sends back the HTTP/304 Not Modified headers, omitting the response body. The client then reuses its copy of the resource from the cache.
On the other hand, if the server determines that the client’s copy of the resource is outdated, the server sends back HTTP/200 OK headers, along with the new response body. The client then uses the new response body, and typically caches it for later reuse.
A client can only send a Conditional Validation request if it has a cached copy of a resource and that copy includes either a Last-Modified or ETag response header. If it lacks both headers, it must request the resource unconditionally, and the server must send back the complete resource.
Why are Conditional Requests Made
Conditional validation delivers a performance improvement when users revisit a page (because the server may omit retransmitting all response bodies) but it still has a cost—the client must generate a conditional request for each resource and wait for the server to return a HTTP/304 response. Ideally, the server will follow best practices and specify Cache-Control or Expires directives on its responses so that the client knows how long they are valid and can skip the validation step and simply use the cached response immediately. However, even if the server supplies such information, conditional validation can still occur:
- After the expiration time specified by the server
- If the user refreshes their browser
For instance, in the Request Headers above, you see a Pragma: no-cache header sent by the browser, a hint that the user has hit F5 to refresh the page. On the other hand, if the user hits CTRL-F5 (sometimes called a “hard refresh”) you will find that the browser omits all of the If-Modified-Since and If-None-Match headers, re-requesting each resource unconditionally.
Avoiding Conditional Requests
In general, caching is a great thing, and is one of the most important things you can do to speed up your website. However, when debugging, it can sometimes be helpful to prevent caching to ensure that you’re always looking at the latest live resources. So, you’re still probably wondering “Without changing the website, how can I make Fiddler avoid the 304 and get back a HTTP/200 with a response body?”
The very simplest way is to just select the HTTP/304 response in the Web Sessions list and press the U key—Fiddler will Unconditionally reissue the selected requests. As you can see in the comparison below, Fiddler has omitted the conditional headers from the reissued request:
If you want to try to prevent HTTP/304s in general, you can clear the browser’s cache, either using the Clear Cache button in Fiddler’s toolbar (for Internet Explorer), or by pressing CTRL+SHIFT+DELETE in the browser (any browser). This will ensure that the browser starts with a cleared cache and will ensure that each resource is downloaded completely at least once. After clearing the browser’s cache, go back to Fiddler and check the Rules > Performance > Disable Caching menu item. When this rule is enabled, Fiddler will remove all conditional validation headers from requests and all cache-directives from responses. Additionally, it will add a Pragma: no-cache request header and a Cache-Control: no-cache response header to help prevent cached copies from being used.