强,协商缓存参考
缓存分为两种:强缓存和协商缓存,根据响应的header内容来决定。
强缓存相关字段有expires,cache-control。如果cache-control与expires同时存在的话,cache-control的优先级高于expires。
协商缓存相关字段有Last-Modified/If-Modified-Since,Etag/If-None-Match
cache-control是直接不发送请求,而ETag是发送请求,但是如果md5相同就不下载,响应体是空的
Etag和If-None-Match
Etag/If-None-Match返回的是一个校验码。ETag可以保证每一个资源是唯一的,资源变化都会导致ETag变化。服务器根据浏览器上送的If-None-Match值来判断是否命中缓存。
与Last-Modified不一样的是,当服务器返回304 Not Modified的响应时,由于ETag重新生成过,response header中还会把这个ETag返回,即使这个ETag跟之前的没有变化。
Last-Modify/If-Modify-Since
浏览器第一次请求一个资源的时候,服务器返回的header中会加上Last-Modify,Last-modify是一个时间标识该资源的最后修改时间
当浏览器再次请求该资源时,request的请求头中会包含If-Modify-Since,该值为缓存之前返回的Last-Modify。服务器收到If-Modify-Since后,根据资源的最后修改时间判断是否命中缓存。
如果命中缓存,则返回304,并且不会返回资源内容,并且不会返回Last-Modify。
Last-Modified与ETag是可以一起使用的,服务器会优先验证ETag,一致的情况下,才会继续比对Last-Modified,最后才决定是否返回304。
强缓存、协商缓存什么时候用哪个
希望服务器上的资源更新了浏览器就请求新的资源,没有更新就使用本地的缓存,以最大程度的减少因网络请求而产生的资源浪费。
image.png
<!DOCTYPE html><html xmlns="http://www.w3.org/1999/xhtml"><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<img src="images/head.png" />
<a href="page.html">重新访问page页</a></body></html>
首次访问该页面,页面中 head.png 响应头部分信息如下:
HTTP/1.1 200 OK
Cache-Control: no-cache
Content-Type: image/png
Last-Modified: Tue, 08 Nov 2016 06:59:00 GMT
Date: Thu, 10 Nov 2016 02:48:50 GMT
问题1:点击“重新访问 page 页”重新加载该页面后, head.png 如何二次加载?
问题2:将 Cache-Control 设置为 private,结果如何?
Http 缓存头是如何协同工作的
缓存存储策略
用来确定 Http 响应内容是否可以被客户端缓存,以及可以被哪些客户端缓存
Cache-Control 头里的以下:
public 指令规定了将资源作为公共缓存,可以被多个用户使用,一般存储在代理服务器中。
private 指令规定了将资源作为私有缓存,只能被单独用户使用,一般存储在用户浏览器中。
no-cache 指令规定缓存服务器需要先向源服务器验证缓存资源的有效性,只有当缓存资源有效时才能使用该缓存对客户端的请求进行响应。Cache-Control: no-cache
相当于 Cache-Control: max-age=0
no-store
指令规定不能对请求或响应的任何一部分进行缓存
以上无法确定本地缓存的数据是否可用(可能已经失效),还必须借助一套鉴别机制来确认才行, 这就是
缓存过期策略
看本地的缓存数据是否已过期,是否可直接从本地缓存数据中加载数据并展示(否则就发请求到服务端获取)
Expires 指名了缓存数据有效的绝对时间,告诉客户端到了这个时间点(比照客户端时间点)后本地缓存就作废了,或者用 Cache-Control 中的max-age,优先级还高于 Expires
缓存数据标记为已过期只是告诉客户端不能再直接从本地读取缓存了,并不等同于本地缓存数据没用了
缓存对比策略
将缓存在客户端的数据标识发往服务端,服务端通过标识来判断客户端缓存数据是否仍有效,进而决定是否要重发数据
检测到数据过期重新发起一个 http 请求到服务器,服务器先看请求头有没有带标识( If-Modified-Since、If-None-Match),如果判断标识仍然有效,则返回304告诉客户端取本地缓存数据来用即可(这里要注意在首次响应时输出相应的头信息(Last-Modified、ETags)到客户端)
参考
网友评论