浏览器强缓存和协商缓存
浏览器第一次访问资源时,会根据返回response Header进行资源缓存,如果返回的response Header中有强缓存字段expires、cache-control则代表资源为强缓存,Last-Modified、ETag留作协商缓存使用。在第二次访问资源时,如果命中了强缓存,则直接返回资源,状态为200。没命中就进入协商缓存阶段,通过Last-Modified/If-Modified-Since、ETag/If-None-Match进行协商缓存,协商缓存命中就返回资源,状态为304,否则请求资源,看情况更新缓存。
注意:相同条件下cache-control的优先级大于expires。ETag的优先级大于last-modified
强缓存字段:
-
Expires expires是http1.0的缓存设置字段,值为时间戳,表示的是资源到期的时间。如果在时间范围内,则直接返回资源,否则代表过期了,需要重新请求跟新。
缺点:时间的的判断是根据本地时间来的,本地的时间可修改,不可信。
-
Cache-Control cache-control是http1.1的缓存字段,优先级高于expires。取值:
-
public:资源客户端和服务器都可以缓存。 -
privite:资源只有客户端可以缓存。 -
no-cache:客户端缓存资源,但是是否缓存需要经过协商缓存来验证。 -
no-store:不使用缓存。 -
max-age:缓存保质期,单位是秒,表示之后多长时间有效,解决expires问题
协商缓存字段
-
Last-Modified(响应值)/If-Modified-Since(请求值) last-modified告诉浏览器这个资源最后的修改时间。服务器将资源传递给客户端时,会将资源最后更改的时间以“Last-Modified: GMT”的形式加在实体首部上一起返回给客户端。注意时间的最小修改单位是1s。
-
ETag(响应值)/If-None-Match(请求值) ETag告诉浏览器当前资源在服务器的唯一标识符(生成规则由服务器决定)
缓存请求流程图
不能缓存的请求
-
HTTP信息头中包含Cache-Control:no-cache,pragma:no-cache(HTTP1.0),或Cache-Control:max-age=0等告诉浏览器不用缓存的请求
-
POST请求无法被缓存
-
HTTP响应头中不包含Last-Modified/Etag,也不包含Cache-Control/Expires的请求无法被缓存
有Last-Modified为什么还要ETag
1.Last-Modified标注的最后修改只能精确到秒级,如果某些文件在1秒钟以内,被修改多次的话,它将不能准确标注文件的新鲜度
2.如果某些文件会被定期生成,当有时内容并没有任何变化,但Last-Modified却改变了,导致文件没法使用缓存
3.有可能存在服务器没有准确获取文件修改时间,或者与代理服务器时间不一致等情形
浏览器操作对缓存的影响
| 浏览器相关操作 | Expires/Cache-Control | Last-Modified / Etag |
|---|---|---|
| 地址栏回车 | 有效 | 有效 |
| 页面链接跳转 | 有效 | 有效 |
| 新开窗口 | 有效 | 有效 |
| 前进、后退 | 有效 | 有效 |
| 刷新 | 无效 | 有效 |
| 强制刷新 | 无效 | 无效 |