Chrome - why is it sending if-modified-since reque

2020-01-31 01:43发布

问题:

I have a page with lots of small images (icons). When used with chrome, each time the page is reloaded, chrome requests each icon from the server with if-modified-since header.

All icons are served with expires and max-age headers. Firefox loads images from its cache.

Why is chrome doing that and how can I prevent it?

Thanks

回答1:

Have you checked the request headers?

"‘Cache-Control’ is always set to ‘max-age=0′, no matter if you press enter, f5 or ctrl+f5. Except if you start Chrome and enter the url and press enter."

http://techblog.tilllate.com/2008/11/14/clientside-cache-control/



回答2:

With chrome it matters whether you're refreshing a page or simply visiting it.

When you refresh, chrome will ping the server for each file regardless of whether or not they are already cached. If the file hasn't been modified you should see a 304 Not Modified response. If the file has been modified you'll see a 200 OK response instead.

When not refreshing, cached files will have a 200 OK status but if you look in the size/content column of the network panel you'll see (from cache).



回答3:

Google Chrome will ignore the Expires header if it's not a valid date by the RFC. For instance, it always requires days to be specified as double-digits. 1st of May should be set as "01 May" (not "1 May") and so on. Firefox accepts them, this misleads the user that the problem is at the browser (this case, Chrome) and not the header values themselves.

So, if you are setting the expire date manually (not using mod_expires or something similar to calculate the actual date) I recommend you to check your static file headers using REDbot.



回答4:

A quick experiment with Chrome’s inspector shows that this only happens when the page is reloaded, not when it is loaded normally. Chrome is just trying to refresh its cache. Think about it — if you set Expires and Max-Age to several decades, are you asking the browser to cache that resource and never check to see if it gets updated? It’s caching the resource when it can, but when the page needs to be refreshed it wants to make sure that the entire page is refreshed. Other browsers surely do it too (although some have an option for the number of hours to wait before refreshing).

Thanks to modern browsers and servers, refreshing a large number of icons won’t be as slow as you think — requests are pipelined to eliminate multiple round-trip delays, and the entire purpose of the If-Modified-Since header is to allow the server to compare timestamps and return a "Not Modified" status code. This will happen for every resource the page needs, but the browser will be able to make all the requests at once and verify that none of them have changed.

That said, there are a few things you can do to make this easier:

  1. In Chrome’s inspector, use the resources tab to see how they are being loaded. If there are no request headers, the resource was loaded directly from the cache. If you see 304 Not Modified, the resource was refreshed but did not need to be downloaded again. If you see 200 OK, it was downloaded again.

  2. In Chrome’s inspector, use the audits tab to see what it thinks about the cacheability of your resources, just in case some of the cache headers aren’t optimal.

  3. All of those If-Modified-Since requests and 304 responses can add up, even though they only consist of headers. Combine your images into sprites to reduce the number of requests.



回答5:

Modern browsers are getting more complex and intelligent with their caching behaviour. Have a read through http://blogs.msdn.com/b/ie/archive/2010/07/14/caching-improvements-in-internet-explorer-9.aspx for some examples and more detail.

As Florian says, don't fight it :-)



回答6:

That sounds like it's trying to avoid an outdated cache by asking the server whether the images have changed since it last requested them. Sounds like a good thing, not something you would like to prevent.



回答7:

Assuming you are running Apache, you can try explicitly setting up cache lifetimes for certain files types and/or locations in the filesystem.

<FilesMatch ".(jpg|jpeg|png|gif)$">
Header set Cache-Control "max-age=604800, public" # 7 days
</FilesMatch>

or something like

ExpiresByType image/jpeg "access plus 7 days"
ExpiresByType image/gif "access plus 7 days"
ExpiresByType image/png "access plus 7 days"

Typically, I will group types of files by use in a single directory and set lifetimes accordingly.

Browsers should not request files at all until this ages have expired, but may not always honor it. You may want/need to futz with Last-Modified and ETag headers. There is lots of good info on the web about this.