浏览器发出的所有 HTTP 请求首先会转至浏览器缓存,用于检查是否存在可满足请求的有效缓存响应。如果存在匹配,则从缓存中读取响应,从而消除网络延迟和传输产生的数据成本。
HTTP响应头:配置 web 服务器
通常通过配置服务器响应头来配置HTTP缓存
Cache-Control
。服务器可以返回Cache-Control
响应头来指定浏览器的缓存方式。Etag
。当浏览器发现过期的缓存响应时,它可以向服务器发送一个小令牌(通常是文件内容的哈希)来检查文件是否已更改。如果服务器返回了相同的令牌,那么说明文件没有改动,无需重新下载。、Last-Modified
。此标头的用途与ETag
相同,但它通过比较时间来确定资源是否已更改,而不是像 ETag 那样通过比较内容。
Cache-Control
有如下属性
no-store
:不缓存。no-cache
:缓存在浏览器,但每次都需要询问服务端,通过对比Etag
和Last-Modified
的值来判断是否过期,ETag
的优先级更高。如果文件没有更新则响应304 Not Modified
否则返回200 OK
。max-age
:用于判断本地缓存是否过期,_Cache-Control: max-age=120_
代表两分钟后过期,在HTTP1.0
中使用expires
响应头来设置过期时间,如果文件判定为未过期,则直接返回缓存中文件无需请求服务器。pubilc
:设定启用用缓存服务器缓存。private
:设定只能在浏览器缓存。
最佳应用
版本化 URL 的长期缓存
假设您的服务器指示浏览器将 CSS 文件缓存 1 年( Cache-Control: max-age=31536000
),但设计师刚刚进行了紧急更新,您需要立即推出此更新。那么如何通知浏览器更新文件的“陈旧”缓存副本呢?您做不到这点,除非修改资源的 URL。浏览器将响应缓存后会一直使用缓存版本,直到它不再是最新的(由 max-age
或 expires
决定),或者直到它因某些其他原因被从缓存中删除:例如用户清除浏览器缓存。因此,在构建页面时,不同的用户最终可能会使用不同版本的文件:刚刚获取资源的用户使用新版本,而缓存较早(但仍然有效)副本的用户使用响应的旧版本。客户端缓存和快速更新,如何两全其美呢?您更改资源的 URL 并强制用户在其内容更改时下载新响应。通常来说,您可以通过在文件名中嵌入文件的指纹或版本号来实现这一点,例如,style.x234dff.css
。
非版本化 URL 的服务器重新验证
对于总是要更新的内容设置Cache-Control:no-cache
,每次请求都会访问服务器,而服务器通过对比Etag
和Last-Modified
的值来确定响应内容。
HTTP 缓存决策指南
- 判断响应是否可重用,不可则设置为
no-store
。 - 判断是否每次都需要服务端确认,是则设置为
no-cache
。 - 判断是否允许中间服务器缓存,是则设置为
public
,否则设置为private
。 - 需要设置最长时间?设置
max-age
。 - 添加
ETag
和last-modified
。