etag 是怎么计算出来的?
nginx 中 etag 由响应头的 Last-Modified 与 Content-Length 表示为十六进制组合而成。 为了通知秒级文件变动。
假如我改变文件时间 etag 会改变吗?
所以修改文件时间,etag 会改变
Last-Modified,ETag 与协商缓存
我们知道协商缓存有两种方式
- Last-Modified/if-Modified-Since
- ETag/If-None-Match
既然在 nginx 中 ETag 由 Last-Modified 和 Content-Length 组成,那它便算是一个加强版的 Last-Modified 了,那加强在什么地方呢? Last-Modified 是由一个 unix timestamp 表示,则意味着它只能作用于秒级的改变
举一个例子
server: nginx/1.18.0
last-modified: Tue, 27 Sep 2022 10:34:49 GMT
etag: W/"19f6d-1837e837c5b"
第一段是 content Length
第二段是 last modified
new Date(parseInt('1837e837c5b', 16)).toJSON()
'2022-09-27T10:34:49.819Z'
parseInt('19f6d', 16)
106349
设置 ETag 的位置
https://github.com/nginx/nginx/blob/master/src/http/ngx_http_core_module.c#L1675
打印函数位置
使用场景
如果客户端想要再次检索相同的 URL 资源,它将首先确定 URL 的本地缓存版本是否已过期(通过缓存控制和 Expire 标头)。如果 URL 尚未过期,它将检索本地缓存的资源。如果确定 URL 已过期(已过时),则客户端将向服务器发送一个请求,其中包含其以前在“If-None-Match”字段中保存的 ETag 副本。
如果判断未过期,服务端范围 304.