Last-Modified 和 ETag 的区别

为什么协商缓存需要 ETag 而不只用 Last-Modified

问题

协商缓存中已经有了 Last-Modified,为什么还需要 ETag

解答

ETag 的出现是为了解决 Last-Modified 在某些场景下的局限性。

Last-Modified 的局限

1. 精度问题

Last-Modified 只能精确到秒级。如果文件在 1 秒内被多次修改,Last-Modified 无法检测到这些变化。

Last-Modified: Wed, 21 Oct 2024 07:28:00 GMT

2. 服务器时间不准确

某些服务器无法精确获取文件的最后修改时间,导致 Last-Modified 不可靠。

3. 内容未变但时间变了

文件被重新保存或移动后,修改时间会改变,但内容可能完全相同。这会导致不必要的资源重新下载。

# 文件内容未变,但修改时间更新了
touch index.js

ETag 的优势

ETag 基于文件内容生成唯一标识,只要内容不变,ETag 就不变。

ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4"
If-None-Match: "33a64df551425fcc55e4d42a148795d9f25f89d4"

服务器对比 ETag 值,如果匹配则返回 304 Not Modified,否则返回新资源。

关键点

  • Last-Modified 只能精确到秒,无法处理秒级以下的文件修改
  • 文件内容未变但修改时间改变时,Last-Modified 会误判需要更新
  • ETag 基于内容生成,只要内容相同就能准确命中缓存
  • ETag 优先级高于 Last-Modified,两者可以同时使用