響應頭中的 ETag 值是如何生成的


要求

  • 當文件不會更改時,ETAG 值保持不變。
  • 計算速度快,耗費CPU資源少
  • 便於擴展,多個服務器上此資源生成的 ETAG 值要相同。

nginx 中 ETag 的生成

Content-Length: 612
Last-Modified: Tue, 23 Apr 2019 10:18:21 GMT
ETag: "5cbee66d-264"

計算規則

new Date(parseInt('5cbee66d', 16) * 1000).toJSON()
"2019-04-23T10:18:21.000Z"
> parseInt('264', 16)
612

express 采用 etag 庫生成

靜態資源一般都只是生成的長度-時間戳而已,

動態接口可以配置,可以算hash。

app.set('etag', true); // weak ETag,長度-時間戳
app.set('etag', 'strong'); // strong ETag, hash
app.set('etag', function (body, encoding) {
  return generateHash(body, encoding); // consider the function is defined
});

核心代碼詳細見這里,截取一小段:

function etag (entity, options) {
  // ...
  // generate entity tag
  var tag = isStats
    ? stattag(entity)
    : entitytag(entity)

  // ...
}

function entitytag (entity) {
  if (entity.length === 0) {
    // fast-path empty
    return '"0-2jmj7l5rSw0yVb/vlWAYkK/YBwk"'
  }

  // compute hash of entity
  var hash = crypto
    .createHash('sha1')
    .update(entity, 'utf8')
    .digest('base64')
    .substring(0, 27)

  // compute length of entity
  var len = typeof entity === 'string'
    ? Buffer.byteLength(entity, 'utf8')
    : entity.length

  return '"' + len.toString(16) + '-' + hash + '"'
}
function stattag (stat) {
  var mtime = stat.mtime.getTime().toString(16)
  var size = stat.size.toString(16)

  return '"' + size + '-' + mtime + '"'
}

真實線上靜態資源文件的Etag。

ETag: "713-1551786316000"
Last-Modified: Tue, 05 Mar 2019 11:45:16 GMT


ETag: "SAdqG/HfsklgQeEc+r/SZg=="
Last-Modified: Thu, 16 Jan 2020 06:17:05 GMT

而 koa 的 etag 插件底層還是 express 的 etag。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM