你知道 http 响应头中的 ETag 是如何生成的吗
source link: http://www.cnblogs.com/xianwang/p/12019830.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
关于 etag
的生成需要满足几个条件
-
当文件不会更改时,
etag
值保持不变。所以不能单纯使用inode
-
便于计算,不会特别耗 CPU。这样子
hash
不是特别合适 -
便于横向扩展,多个
node
上生成的etag
值一致。这样子inode
就排除了
关于服务器中 etag
如何生成可以参考 HTTP: Generating ETag Header
那么在 nginx
中的 etag
是如何生成的?
nginx 中 ETag 的生成
我在网上找到一些资料与源代码了解到了 etag
的计算方法。由 python
伪代码表示计算方法如下
etag = '{:x}-{:x}'.format(header.last_modified, header.content_lenth)
etag->value.len = ngx_sprintf(etag->value.data, "\"%xT-%xO\"", r->headers_out.last_modified_time, r->headers_out.content_length_n) - etag->value.data;
总结: nginx
中 etag
由响应头的 Last-Modified
与 Content-Length
表示为十六进制组合而成。
随手在我的k8s集群里找个 nginx
服务测试一下
$ curl --head 10.97.109.49 HTTP/1.1 200 OK Server: nginx/1.16.0 Date: Tue, 10 Dec 2019 06:45:24 GMT Content-Type: text/html Content-Length: 612 Last-Modified: Tue, 23 Apr 2019 10:18:21 GMT Connection: keep-alive ETag: "5cbee66d-264" Accept-Ranges: bytes
由 etag
计算 Last-Modified
与 Content-Length
,使用 js
计算如下,结果相符
> new Date(parseInt('5cbee66d', 16) * 1000).toJSON() "2019-04-23T10:18:21.000Z" > parseInt('264', 16) 612
Last-Modified,ETag 与协商缓存
我们知道协商缓存有两种方式
-
Last-Modified
/if-Modified-Since
-
ETag
/If-None-Match
既然在 nginx
中 ETag
由 Last-Modified
和 Content-Length
组成,那它便算是一个加强版的 Last-Modified
了,那加强在什么地方呢?
** Last-Modified
是由一个 unix timestamp
表示,则意味着它只能作用于秒级的改变**
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK