Expires和Cache-Control
Expires: Http1.0
Cache-Control: Http1.1
Expires和max-age规定了缓存失效的时间
理论上两个应该是相等的。如果两者同时存在,max-age优先级更高。
浏览器缓存过期后常见处理方式
服务器发送每个资源的时候,都会标明一个有效期,指在该有效期内资源不会更新。但在实际情况下,该有效期过了之后,该资源其实也并没有更新,这个时候浏览器有两种策略。
-
Last-Modified / If-Modified-Since
服务端在告诉客户端约定的有效期的同时,告诉客户端的最后修改时间。客户端在有效期过后(浏览器强制刷新可以忽略max-age和Expires直接向发服务请求),发送该最后修改日期,当再次下载该文件时,对比时间有没有变化,没有则继续使用缓存。主要使用Last-Modified / If-Modified-Since。需要配合cache-control使用。
比方说请求一个资源,服务端返回了Last-Modified字段
然后我在主页按下ctrl+r刷新,因为ctrl+r会默认跳过max-age和Expires的检验直接去向服务器发送请求,我们看看请求截图:
request.png
请求头的的If-Modified-Since字段值与服务器返回的Last-Modified相同。
相同的情况下,响应304,从缓存读取数据。如果不相同则请求数据(如无意外返回200),记录新的Last-Modified字段。
-
E-tag / If-None-Match
E-tag是服务器资源的唯一标识符,用于判断资源是否有修改过。当客户端请求资源时,服务区返回E-tag字段。当客户端发现缓存过期了,就在请求中发送 If-None-Match字段,值为服务器上次返回的E-tag。服务端通过校对E-tag值是否改变告诉客户端资源是否可用。如果可用,返回304,从缓存中获取资源,否则请求资源返回200。同样需要配合cache-control使用。
当上述两种方式同时存在时,E-tag / If-None-Match优先。或许你会问为什么它优先?两者功能相似甚至相同,为什么要同时存在?HTTP1.1中的E-tag为了解决以下问题:
- Last-Modified职能精确到秒,如果一秒内多次修改则不能准确标注修改时间
- 如果某些文件定期生成,但是文件内容并没有改变。导致没法使用缓存。
- 有可能存在服务器没有准确获取文件修改时间或者与代理服务器不一致的情况。
不能缓存的请求
并不是所有的请求都能被缓存
无法被浏览器缓存的请求:
- HTTP头部信息包含Cache-Control:no-cache,pragma:no-cache(HTTP1.0),或者Cache-Control:max-age=0等告诉浏览器不用缓存的请求。
- 需要经过Cookie,认证信息等决定输入内容的动态请求不能被缓存
- 经过HTTPS加密的请求
- POST请求无法被缓存
- HTTP响应头部不包含Last-Modified/Etag,也不包含Cache-Control/Expires的请求
Cache-Control内含字段
请求和响应头部均可设置的字段:
no-store: 请求和响应都不缓存
no-cache: 相当于max-age:0, must-revalidate。即资源被缓存,但是立刻过期,下次访问强制验证资源有效性
max-age:缓存资源多少秒后过期
no-transform: 强制要求代理服务器不对资源进行转换,禁止代理服务器对Content-Encoding,Content-Range,Content-Type字段的修改(因此代理的gzip的压缩将不被允许)
响应头部字段:
public:资源将被客户端和代理服务器缓存
private:资源只能被客户端缓存,代理服务器不能缓存
s-maxage: 以来public设置,覆盖max-age,只在代理服务器上有效。
must-revalidation / proxy-revalidation : 如果缓存失效,强制重新向服务器发起验证(因为max-stale可能改变缓存的失效时间)
请求头部字段
max-stale : 指定时间内,即使缓存过期,资源依然有效
min-fresh : 缓存资源至少要保持指定时间的新鲜期(例如该值为一天,则在max-age减去一天时缓存就失效)
only-if-cache : 仅访问缓存,不访问网络,若无缓存则返回504
用户操作对缓存的影响
Mac
command + shift + R 强制刷新,忽略一切缓存,可以看到状态码返回200
command + R 相当于重新请求,缓存有效。返回304
网友评论