文章摘要
Cache-Control、ETag、Last-Modified 之间的关系,以及带指纹的静态资源应该怎么配。
缓存配错了,要么用户看到旧页面,要么服务器白白多扛几倍请求。两种缓存的职责要分清楚。
强缓存:不发请求
响应头里的 Cache-Control 说了算,命中时浏览器直接用本地副本,Network 面板显示 200 (from disk cache)。
BASH
Cache-Control: public, max-age=31536000, immutableimmutable 告诉浏览器:即便用户点了刷新也别来问我。只有文件名带哈希的资源才敢这么写。
协商缓存:发请求,可能返回 304
强缓存过期后,浏览器带着标识去问服务器。
ETag/If-None-Match:内容指纹,优先级更高,能解决同一秒内修改的问题Last-Modified/If-Modified-Since:秒级精度,够用且开销小
JS
res.setHeader('ETag', '"' + crypto.createHash('sha1').update(body).digest('hex').slice(0, 16) + '"');
if (req.headers['if-none-match'] === etag) { res.writeHead(304); return res.end(); }一套实用的组合
- HTML:
no-cache,每次都要问服务器,保证发版即时生效 - 带哈希的静态资源:
max-age=31536000, immutable - 接口数据:
no-store,或者按业务给几十秒的短 max-age
关键点是 HTML 必须不缓存。只要 HTML 拿到的是新版,里面引用的资源哈希就一定是新的。
容易忽略的两件事
- 304 依然要一次完整的网络往返,移动端弱网下首屏照样慢,别把 no-cache 用在资源上
- CDN 和 Nginx 会重写缓存头,本地验证通过后还要再看一遍线上响应头
留言板0
昵称必填 · 邮箱仅用于生成头像
还没有留言,来坐第一排
1231231😭
第一条留言,测试<script>alert(1)</script>