Dec 24, 2013

f Comment

How Are Static Files Cached By Web Browsers? A Detailed Example Included!

If you are a website developer you probably wonder how static files are cached by the browser. How does the browser know whether a requested resource, in this case a static file such as an image, has been cached by the browser cache and therefore does not need to be sent over to the browser again? In this article you'll find all the details.

I'll be using Firefox 20.0 as the web browser, which uses HTTP/1.1 protocol. You can find details about HTTP 1.1 header field definitions at http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.4.

1st HTTP Request

Let's say that I have never visited http://direct.chtoen.com/image/%E8%A6%96%E5%8A%9B.jpg before. In Firefox 20.0 when I make a request to http://direct.chtoen.com/image/%E8%A6%96%E5%8A%9B.jpg, the browser sends the following HTTP headers.

Accept text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Encoding gzip, deflate
Accept-Language en-US,en;q=0.5
Connection keep-alive
Cookie ...
Host direct.chtoen.com
User-Agent Mozilla/5.0 (Windows NT 6.1; WOW64; rv:20.0) Gecko/20100101 Firefox/20.0

The following is the HTTP response from my Nginx 1.4.1 web server.

status code 200 OK
Cache-Control max-age=2592000
Connection keep-alive
Content-Encoding gzip
Content-Type image/jpeg
Date Tue, 24 Dec 2013 08:16:11 GMT
Expires Thu, 23 Jan 2014 08:16:11 GMT
Last-Modified Sun, 10 Nov 2013 14:29:51 GMT
Server nginx/1.4.1
Transfer-Encoding chunked
Vary Accept-Encoding

The server then sends the entire image to the client. Now Firefox caches this image in its browser cache (which is just a directory) and associates with it the date 'Sun, 10 Nov 2013 14:29:51 GMT'.

2nd HTTP Request

I made a new request to the same image http://direct.chtoen.com/image/%E8%A6%96%E5%8A%9B.jpg, the browser sends the following HTTP headers.

Accept text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Encoding gzip, deflate
Accept-Language en-US,en;q=0.5
Cache-Control max-age=0
Connection keep-alive
Cookie ...
Host direct.chtoen.com
If-Modified-Since Sun, 10 Nov 2013 14:29:51 GMT
User-Agent Mozilla/5.0 (Windows NT 6.1; WOW64; rv:20.0) Gecko/20100101 Firefox/20.0

As you can see the browser sends an extra header compared to the first HTTP request, If-Modified-Since, because Firefox knows that this image was last modified on "Sun, 10 Nov 2013 14:29:51 GMT". Let's see how the server responds. The following is the HTTP response from my Nginx 1.4.1 web server.

status code 304 Not Modified
Cache-Control max-age=2592000
Connection keep-alive
Date Tue, 24 Dec 2013 08:16:33 GMT
Etag "527f985f-31b8"
Expires Thu, 23 Jan 2014 08:16:33 GMT
Last-Modified Sun, 10 Nov 2013 14:29:51 GMT
Server nginx/1.4.1

The server does NOT send the image to the client at all. As you can see the server just sends "304 Not Modified" and that's it.

A fun observation is my Nginx 1.4.1 server does NOT send Etag the first time around. It sends Etag in the following responses. I've tested the same scenario with Apache 2.2.3 (CentOS) and it sends Etag the first time. So this difference can be due to their server configuration settings.

In conclusion the HTTP client (the Firefox browser in this case) and the HTTP server (the Nginx web server in this case) need to work together to make use of browser caching.


Questions? Let me know!
Please leave a comment here!
One Minute Information - by Michael Wen
ADVERTISING WITH US - Direct your advertising requests to Michael