先用一张图来展示浏览器缓存机制:
浏览器缓存分两种:强制缓存和协商缓存。
强制缓存
强制缓存主要是通过Expires和Cache-Control。
Cache-Control字段
cache-control: no-store:不缓存,这个会让客户端、服务器都不缓存,也就没有所谓的强缓存、协商缓存了。
cache-control: no-cache:协商缓存
cache-control: max-age=xxxx,private:只允许客户端可以缓存该资源;代理服务器不允许缓存;客户端在xxx秒内直接读取缓存, statu code: 200
cache-control: max-age=xxxx,public:客户端和代理服务器都可以缓存该资源;客户端在xxx秒的有效期内,如果有请求该资源的需求的话就直接读取缓存, statu code: 200;
所以想设置强制缓存,可通过设置cache-control字段:
cache-control: max-age=xxxx,private
或者
cache-control: max-age=xxxx,s-maxage=xxx,public
max-age,s-maxage设置的是相对时间,s-maxage多用于公共缓存服务器
用户操作浏览器的行为也会决定cache-control有没有效果
还可以通过设置Expires:xxxx,expires设置的是绝对时间
协商缓存
当服务器响应头cache-control: no-cache,或者设置强缓存但是当缓存过期之后,未必缓存就不能使用,所以要和服务器协商判断缓存是否能使用,这些情况都涉及到协商缓存。
协商缓存通过Etag/If-None-Match,last-Modified/If-Modified-Since。
Etag/If-None-Match:
都是服务器为资源分配到唯一标识。当客户端请求资源时,服务器会在http响应头设置Etag,资源变化Etag也会随之变化。再次请求资源时,请求头带上If-None-Match。如果Etag和If-None-Match一致,则返回状态码为304的响应,继续使用缓存。如果不一致则获取更新后的资源返回给前端。
last-Modified/If-Modified-Since:
文件的修改时间(绝对时间),精确到秒。
当客户端请求资源时,服务器会在http响应头设置last-Modified,资源变化last-Modified也会随之变化。再次请求资源时,请求头带上If-Modified-Since,如果last-Modified和If-Modified-Since一致,则返回状态码为304的响应,继续使用缓存。如果不一致则获取更新后的资源返回给前端。
Etag/If-None-Match较之 last-Modified/If-Modified-Since的优势:
a、last-Modified精确到的时间是秒,所以如果资源在秒内即是变化了last-Modified也不会改变,那么其实协商缓存判断的结果就不准确了。
b、一些服务器的资源可能会周期性的更改,但是其实内容是没有变的,但last-Modified变了,就得重新从服务器加载资源。
c、某些服务器不能精确的得到服务器的修改时间。
缓存机制的应用场景
读多写少的数据。
备注:如有不准确,后续会进行改进。参考文章https://www.cnblogs.com/cckui/p/11506514.html、https://segmentfault.com/a/1190000015816331、https://www.cnblogs.com/skylar/p/browser-http-caching.html
网友评论