浏览器缓存机制有两种:HTML Meta标签、HTTP头信息
1、HTML meta标签
可以在HTML页面的<head>节点中加入<meta>标签:
<meta http-equiv="Pragma" content="no-cache">
上述代码的作用是告诉浏览器当前页面不被缓存,每次访问都需要去服务器拉取。使用上很简单,但只有部分浏览器可以支持,而且所有缓存代理服务器都不支持,因为代理不解析HTML内容本身。
2、HTTP头信息
浏览器缓存机制,其实主要是HTTP协议定义的缓存机制(如Expires;Cache-control等)。广泛应用的是HTTP头信息来控制缓存。
1) Expires策略:
<meta http-equiv="Expires" content="Sun, 31 Dec 2017 23:59:59 GMT" />
在HTML中设置meta的Expires需要Web服务器支持,但基本上现在的主流服务器都不会识别这个Tag,因此不建议这样设置。
Expires是服务器响应消息头字段,在响应http请求时,告诉客户端在过期时间前,客户端可以直接从浏览器缓存读取数据(200 from cache),而无需再次请求。
然而,由于Expires是HTTP 1.0的,而现在默认客户端均默认使用HTTP 1.1,所以Expires的作用基本忽略。
Expires的缺点:返回的到期时间是服务器端的时间,如果客户端的时间与服务器的时间相差很大(如时钟不同步或跨时区),那么误差就很大。所以在HTTP 1.1开始,使用“Cache-Control: max-age=秒”替代。
2) Cache-control策略:
<meta http-equiv="Cache-Control" content="max-age=2400" />
在HTML中设置meta的Cache-Control需要Web服务器支持,但基本上现在的主流服务器都不会识别这个Tag,因此不建议这样设置。
Cache-Control与Expires的作用相同,都是指明当前资源的有效期,控制客户端是直接从浏览器缓存取数据还是重新发请求到服务器读取数据。但是Cache-Control的选择更多,如果同时设置,其优先级高于Expires。
① Public:响应可被任何缓存区缓存。
② Private:对于单个用户的整个或部分响应消息,不能被共享缓存处理。这允许服务器仅仅描述当前用户的部分响应消息,此响应消息对于其他用户的请求无效。
③ no-cache:请求或响应消息不能缓存。
④ no-store:防止重要的信息被无意的发布。在请求消息中发送将使得请求和响应消息都不使用缓存,完全不存下來。
⑤ max-age:客户端可以接收生存期不大于指定时间(以秒为单位)的响应。
⑥ min-fresh:客户端可以接收响应时间小于当前时间加上指定时间的响应。
⑦ max-stale:客户端可以接收超出超时期间的响应消息。如果指定max-stale消息的值,那么客户机可以接收超出超时期指定值之内的响应消息。
3) Last-Modified/If-Modified-Since:要配合Cache-Control使用。
① Last-Modified:标示当前资源的最后修改时间。服务器在响应请求时,会将资源最后更改的时间以“Last-Modified: GMT”的形式加在响应消息包体头部上一起返回给客户端。客户端会为资源标记上该信息,下次再次请求时,会附带 头 If-Modified-Since给服务器,比较其与服务器上该资源的最后修改时间,来判断该资源是否被修改过,决定返回200状态码和整个资源内容还是直接返回304状态码和响应消息包头。
② If-Modified-Since:当资源过期时(超过Cache-Control中的max-age),若发现资源具有Last-Modified声明,则再次向服务器请求时带上头 If-Modified-Since(Last-Modified的值)。服务器收到请求后发现带有头If-Modified-Since ,则与资源的最后修改时间进行比对。若最后修改时间较新,说明资源被修改过,则响应HTTP 200和整个资源内容(写在响应消息包体内);若最后修改时间较旧,说明资源未被修改过,则响应HTTP 304和响应消息包头(无需响应消息包体),告知客户端直接从浏览器缓存取数据。
4) Etag/If-None-Match:要配合Cache-Control使用。
Last-Modified/If-Modified-Since的问题:如果在服务器上一个资源被修改过,但其实际内容并没发生改变,会因为Last-Modified时间匹配不上而返回了整片资源内容(即使浏览器缓存里有一模一样的资源)。
为了解决上述问题,Http1.1还推出了ETag 实体首部字段。但是,Last-Modified与ETag一起使用时,服务器会优先验证ETag。
① Etag:服务器会通过某种算法,给资源计算得出一个唯一标志符,仅仅是一个和文件相关的标记,可以是一个版本标记,如v1.0.0或c782-465-5fe381e7,服务器在响应请求时,会在消息包体头部加上“ETag: 唯一标识符”一起返回给客户端。客户端会为资源标记上该信息,下次再次请求时,会附带头If-None-Match给服务器,比较其与服务器上该资源的ETag是否一致,决定返回200状态码和整个资源内容还是直接返回304状态码和响应消息包头。
② If-None-Match:当资源过期时(超过Cache-Control中的max-age),若发现资源具有Etag声明,则再次向服务器请求时带上头If-None-Match (Etag的值)。服务器收到请求后发现有头If-None-Match 则与资源的ETag进行比对。若ETag不一致,则响应HTTP 200和整个资源内容(写在响应消息包体内,也包括新的ETag);若ETag一致,则响应HTTP 304和响应消息包头(无需响应消息包体)。
3、用户操作与浏览器缓存
1) Ctrl+F5强制刷新:
所有缓存都失效, 直接请求服务器返回最新的资源。
2) F5刷新:
Expires和Cache-Control失效,发送请求到服务器, 根据Last-Modified和Etag判断是从浏览器缓存读取数据还是请求服务器返回最新的资源。
3) 地址栏回车or页面链接跳转or新开窗口or前进后退:
所有缓存都生效,先根据Expires和Cache-Control判断资源是否过期,若未过期则直接从浏览器缓存读取数据,否则根据Last-Modified和Etag判断是从浏览器缓存读取数据还是请求服务器返回最新的资源。