Understanding Browser Cache Mechanisms and HTTP Header Controls
This article explains how browsers cache resources, the role of HTTP response headers such as Expires, Cache‑Control, ETag and Last‑Modified, and how conditional requests and different refresh actions affect caching behavior to improve web performance.
During web development, developers often encounter browser caching issues. This article explains the mechanisms behind browser cache, helping readers gain a deeper understanding of how browsers store and validate resources.
Process
When a resource is requested for the first time, the browser sends a typical HTTP request header:
(Request-Line) GET /a.html HTTP/1.1
host 127.0.0.1
User-Agent Mozilla/5.0 (X11; U; Linux i686; zh-CN; rv:1.9.0.15) Gecko/2009102815 Ubuntu/9.04 (jaunty) Firefox/3.0.15
Accept text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language zh-cn,zh;q=0.5
Accept-Encoding gzip,deflate
Accept-Charset gb2312,utf-8;q=0.7,;q=0.7
Keep-Alive 300
Connection keep-aliveThe server responds with a 200 status and includes descriptive headers such as:
(Status-Line) HTTP/1.1 200 OK
date Thu, 26 Nov 2009 13:50:54 GMT
Server Apache/2.2.11 (Unix) PHP/5.2.9
Last-Modified Thu, 26 Nov 2009 13:50:19 GMT
Etag "8fb8b-14-4794674acdcc0"
Accept-Ranges bytes
Content-Length 20
Keep-Alive timeout=5, max=100
Connection Keep-Alive
Content-type text/htmlKey fields include Last-Modified (last modification time), ETag (unique entity tag), and Expires (cache expiration time). The browser stores the file in its cache directory together with these metadata.
On a subsequent request, the browser checks the cache. If the cached file has not expired according to Expires , it serves the file locally without contacting the server.
If the file is expired, the browser sends a conditional request containing the previously received values:
If-Modified-Since Thu, 26 Nov 2009 13:50:19 GMT
If-None-Match "8fb8b-14-4794674acdcc0"The server validates these headers. If the resource has not changed, it returns a 304 Not Modified response, avoiding the transfer of the body:
(Status-Line) HTTP/1.1 304 Not Modified
Date Thu, 26 Nov 2009 14:09:07 GMT
Server Apache/2.2.11 (Unix) php/5.2.9
Connection Keep-Alive
Keep-Alive timeout=5, max=100
Etag "8fb8b-14-4794674acdcc0"This greatly reduces bandwidth usage and improves user experience. If the resource has changed, the server returns the new content with updated headers.
Basic Header Fields
Pragma
The Pragma header carries implementation‑specific directives; the most common is Pragma: no-cache , which is equivalent to Cache-Control: no-cache in HTTP/1.1.
Expires
Specifies the absolute expiration time of the cached file. If the file has not expired, the browser does not send a request.
Cache-Control
Cache-Control defines the caching policy for requests and responses. Request directives include no-cache , no-store , max-age , max-stale , min-fresh , and only-if-cached . Response directives include public , private , no-cache , no-store , no-transform , must-revalidate , proxy-revalidate , and max-age . Their meanings are explained in the list below.
Public : response may be cached by any cache.
Private : response is intended for a single user and must not be stored by shared caches.
no-cache : forces caches to submit the request to the origin server for validation before releasing a cached copy.
no-store : prevents any part of the request or response from being cached.
max-age : specifies the maximum amount of time (in seconds) a resource is considered fresh.
min-fresh : indicates the client is willing to accept a response that will still be fresh for at least the specified number of seconds.
max-stale : allows the client to accept a response that has exceeded its expiration time by up to the specified number of seconds.
ETag / If-None-Match
ETag is a validator that uniquely identifies a specific version of a resource, typically generated from the file's inode, size, and modification time. The client sends If-None-Match with the previously received ETag to enable strong validation.
Last-Modified / If-Modified-Since
These headers work together to validate a resource based on its last modification timestamp.
According to RFC 2616, Expires and Cache-Control control cache freshness, while Last-Modified and ETag validate resource validity.
Last-Modified vs. ETag
ETag is used in addition to Last-Modified because multiple modifications within a single second may not be reflected in the timestamp, whereas an ETag provides a more precise change detection.
Different Scenarios
The basic caching flow changes in real‑world situations such as normal navigation, page refresh, and forced refresh.
Normal Page Navigation
Includes link clicks, window.open , or typing a URL.
Without caching, the request returns all resources.
If Expires is set and not reached, the browser does not issue a request.
If Expires has passed, the browser sends a request with Last-Modified and ETag for server validation.
Page Refresh (F5)
Browsers typically send conditional requests, resulting in many 304 responses even when the resource has not expired. The behavior differs slightly between IE and Firefox.
IE example:
If-Modified-Since Wed, 18 Nov 2009 15:54:52 GMT
If-None-Match "2360492659"
Pragma: no-cache // prohibit cachingFirefox example:
If-Modified-Since Wed, 18 Nov 2009 15:54:52 GMT
If-None-Match "2360492659"
Cache-Control max-age=0 // file expires immediatelyForced Refresh (Ctrl+F5)
The effect is equivalent to a no‑cache request, and the server returns a full 200 response with the resource.
Special Resource Types
IFRAME
FLASH
Asynchronously fetched data (e.g., AJAX)
Disclaimer: The content is sourced from public internet channels, presented neutrally for reference and discussion only. Copyright belongs to the original authors; please contact for removal if infringement occurs.
Art of Distributed System Architecture Design
Introductions to large-scale distributed system architectures; insights and knowledge sharing on large-scale internet system architecture; front-end web architecture overviews; practical tips and experiences with PHP, JavaScript, Erlang, C/C++ and other languages in large-scale internet system development.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.