为什么Etag比last-modified优先级更高?

1、如何设置浏览器缓存

  1. Expires(实体首部字段):服务端返回的到期时间,分为“相对文件的最后访问时间”和“绝对修改时间”。缺点:返回的是服务端时间,比较的是客户端时间,如果不一致可能出现错误

  2. Cache-Control(通用首部字段):

    • private
    • public
    • max-age=xxx:缓存内容在xxx秒后失效
    • no-cache:需要用另一种缓存策略来验证缓存(ETag,Last-Modified)
    • no-store:不进行缓存
  3. **Last-Modified(**实体首部字段):

    • 浏览器请求获得文件后,服务器返回该文件的最后修改时间Last-Modified
    • 下一次请求会带上If-Modified-Since标识,如果If-Modified-Since等于服务器的文件修改时间,则表示文件没有修改,返回304状态码
    • 浏览器从浏览器缓存中读取文件。如果If-Modified-Since小于服务端的文件修改时间,则浏览器会重新发送请求获取文件,返回状态码200
  4. Etag(响应首部字段):服务器文件的唯一标识

    • 服务器返回Etag字段给浏览器,当文件变化时Etag值也会发生变化
    • 下次请求会带上If-None-Match即浏览器保留的ETag值,如果发送了变化,则文件被修改,需要重新请求,返回200状态码
    • 反之浏览器就从缓存中读取文件,返回304状态码

2、 四者区别

  1. 当Cache-Control设置为max-age=xx并且同时设置Expires时,Cache-Control的优先级更高
  2. 当ETag和Last-Modified同时存在时,服务器先会检查ETag,然后再检查Last-Modified,最终决定返回304还是200

3、为何既有last-modified又有Etag

考虑以下情况:

  1. 一些文件也许会周期性的更改,但是他的内容并不改变(仅仅改变的修改时间),这个时候,我们并不希望客户端认为这个文件被修改了,而重新 get
  2. 某些文件修改非常频繁,比如在秒以下的时间内进行修改(比方说 1s 内修改了 N 次),If-Modified-Since能检查到的粒度时 s 级的,这种修改无法判断(或者说 UNIX 记录 MTIME只能精确到秒)
  3. 某些服务器不能精确得到的文件的最后修改时间

所以利用Etag可以更准确的控制缓存。

参考:曾经面试踩过得坑,都在在这里了

猜你喜欢

转载自blog.csdn.net/weixin_43912756/article/details/108481083