Skip to content

浏览器缓存怎么回答? ​

强缓存命中时浏览器不发请求。协商缓存每次都要问服务器,资源没变就返回 304,沿用本地副本。线上页面用「HTML 短缓存或协商,带内容哈希的静态资源长缓存」。

原理 ​

强缓存看 Cache-Control: max-age=...(HTTP/1.1)或过期的 Expires。年龄还没到,直接用磁盘或内存里的副本,状态仍是 200,开发者工具里会标 from disk cache 或 from memory cache。

协商缓存把校验令牌发给服务器:

  • ETag 配请求头 If-None-Match
  • Last-Modified 配 If-Modified-Since

没变化就 304,没有响应体。变了就 200 并带上新内容。两者都在时以 ETag 为准。ETag 能分辨同一秒内的变化,也能避免服务器时间不准;Last-Modified 更便宜。

几个容易混的指令:

  • no-cache:可以存,但使用前必须向服务器验证。它不是「不缓存」。
  • no-store:不写入缓存。
  • private:只允许浏览器缓存,共享缓存(例如中间代理)不行。
  • immutable:在过期前不要为了刷新而重新验证,适合带哈希的文件名。

HTML 如果也缓存一年,用户会一直拿到旧的入口,里面的旧哈希文件名也就不会更新。所以入口文档要能较快失效,静态资源文件名带上内容哈希之后可以缓存很久。

追问 ​

刷新和强刷有什么差别?

普通刷新仍可能走协商缓存。强制刷新会避开缓存重新要一份。地址栏回车更可能直接吃强缓存。面试时说明自己指的是哪一种操作。

协商缓存为什么还要设计?

强缓存期间服务器没法让客户端立刻更新。协商缓存用一次很轻的往返换「变了才下载」。

易错点 ​

  • no-cache 不等于 no-store。
  • 304 是缓存生效,不是出错。
  • 只给 JS/CSS 加长缓存、却不改文件名,用户会一直跑旧脚本。

相关 ​