HTTP缓存
类型
- 强缓存(本地缓存)
- 弱缓存(协商缓存)
流程
访问静态资源时的流程
- 强缓存阶段:先在本地查找是否有该资源,若有,且
Expires和Cache-Control都满足要求,则命中强缓存,返回200,直接返回强缓存中的数据,不会向服务器发出请求。 - 弱缓存阶段:在本地缓存找到该资源,发送http请求到服务器询问该资源是否有更新,若服务器判断没有更新,返回
304Not Modified。则浏览器继续使用该资源。 - 缓存失败阶段:若在本地没有找到对应资源,或者资源已过期/更新,则服务器返回该资源。
强缓存VS弱缓存
- 状态码
强缓存返回200
弱缓存返回304 - 强缓存不需要发出http请求,而弱缓存需要。
强缓存
使用Expires和cache-control来控制。优先级:pragma>cache-control>Expires
Expires服务器为资源设置一个
Expire日期,在这Expire日期之前可以将资源视作最新。此字段是为了兼容旧版本HTTP才保留的,在http1.0时配合pragma使用,pragma:no-cache表示不缓存,pragma的优先级大于ExpiresCache-ControlCache-Control是http1.1为了弥补Expires的缺陷而加入的(http1.0时,使用pragma),当Expires和Cache-Control同时存在时,Cache-Control的优先级高于Expires。
| Cache-Control取值 | 描述 |
|---|---|
| public | 服务器端和浏览器端都可以缓存 |
| private | 只有浏览器可以缓存 |
| no-cache | 强制浏览器在使用cache拷贝之前先提交一个http请求到原服务器进行确认,类似于弱缓存 |
| only-if-cached | 表明客户端只接受已缓存的响应,并且不需要向服务器检查是否有更新的拷贝 |
| max-age=60 | 单位:秒,缓存的有效期,超过这个时间后将被认为过期。此选项会覆盖Expires字段的过期日期 |
| no-store | 不缓存,使用协商缓存 |
| must-revalidate | 缓存必须在使用之前验证旧资源的状态,并且不可使用过期资源 |
弱缓存
有关字段 Last-Modified/If-Modified-Since(HTTP1.0)、Etag/If-None-Match(HTTP1.1)
Last-Modified和Etag为响应头部字段,分别对应请求头部字段中的if-Modifed-Since/If-None-Match。
Last-Modified/If-Modified-Since存在缺陷,当资源的实际内容没有改变而仅仅只是时间变化了(比如只是打开了文件,并保存了一下,尽管内容没有变化但还是修改过),还是需要重新请求资源。因此为了解决这个缺陷,http1.1提出了Etag/If-None-Match,Etag类似于文件的hash,为文件提供了一个指纹,只检查文件内容是否一致。
流程:
- 当没有命中强缓存时,进入弱缓存阶段
- 浏览器首次访问网站时,服务器会在响应头部中附上
Last-Modified/Etag - 弱缓存阶段,浏览器再次访问时,会发送
If-Modified-Since/If-None-Match去询问是否有改变,有则重新获取,否则使用本地缓存。
缓存与浏览器刷新
- F5刷新,会使强缓存失效,浏览器进行协商缓存。
- Ctrl+F5刷新,为强制刷新,强缓存与弱缓存均失效,浏览器总会发送HTTP请求向服务器获取最新数据。