Etag概念和应用

260 阅读4分钟

Etag概念和应用

ETag(Entity Tag,实体标签)是 HTTP 协议中用于标识资源唯一性的一种机制,通常用于缓存控制和条件请求。以下是 ETag 的概念和应用详解:

1. ETag 的概念

  • 定义

    • ETag 是服务器为资源生成的一个唯一标识符,通常是一个字符串。

    • 当资源发生变化时,ETag 也会随之改变。

  • 格式

    • ETag 可以是任意字符串,但通常是一个哈希值或版本号。
ETag: "686897696a7c876b7e"
  • 作用

    • 用于缓存验证:客户端可以通过 ETag 判断资源是否已更新。

    • 用于条件请求:客户端可以通过 ETag 发起条件请求,减少不必要的数据传输。

2. ETag 的应用场景

  • 缓存控制

    • 客户端缓存资源后,可以通过 ETag 验证资源是否过期。
  • 条件请求

    • 客户端在请求资源时,可以附带 ETag,服务器根据 ETag 判断是否需要返回资源内容。
  • 并发控制

    • 在更新资源时,客户端可以通过 ETag 确保资源未被其他客户端修改。

3. ETag 的工作流程

  • 首次请求

(1) 客户端请求资源。

(2) 服务器返回资源,并在响应头中包含 ETag:

HTTP/1.1 200 OK
ETag: "686897696a7c876b7e"
Content-Length: 1234
  • 缓存验证

(1) 客户端再次请求资源时,在请求头中包含上次获取的 ETag:

GET /resource HTTP/1.1
If-None-Match: "686897696a7c876b7e"

(2) 服务器比较客户端提供的 ETag 和当前资源的 ETag:

  • 如果 ETag 匹配,返回 304 Not Modified,不返回资源内容:
HTTP/1.1 304 Not Modified
  • 如果 ETag 不匹配,返回 200 OK 和新资源内容:
HTTP/1.1 200 OK
ETag: "789abc123def456"
Content-Length: 5678

4. ETag 的类型

  • 强 ETag

    • 要求资源的每个字节都完全相同。
ETag: "686897696a7c876b7e"
  • 弱 ETag

    • 允许资源内容有微小变化(如空格、注释)。

    • W/ 开头:

ETag: W/"686897696a7c876b7e"

5. ETag 的生成方式

  • 哈希值

    • 对资源内容计算哈希值(如 MD5、SHA1)。
const crypto = require('crypto');
const content = 'Hello, World!';
const etag = crypto.createHash('md5').update(content).digest('hex');
  • 版本号

    • 使用资源的版本号或修改时间戳。
const version = 'v1.0';
const etag = `"${version}"`;

6. ETag 的优点

  • 减少带宽消耗

    • 通过条件请求避免传输未修改的资源。
  • 提高性能

    • 客户端可以复用本地缓存,减少服务器负载。
  • 支持并发控制

    • 确保资源更新时不会覆盖其他客户端的修改。

7. ETag 的缺点

  • 计算开销

    • 生成 ETag 可能需要计算资源内容的哈希值,增加服务器开销。
  • 隐私问题

    • ETag 可能被用于跟踪用户行为(如浏览器指纹)。
  • 缓存失效问题

    • 如果 ETag 生成方式不合理,可能导致缓存频繁失效。

8. 示例代码

  • 服务器端(Node.js + Express)
const express = require('express');
const crypto = require('crypto');
const app = express();

app.get('/resource', (req, res) => {
  const content = 'Hello, World!';
  const etag = crypto.createHash('md5').update(content).digest('hex');

  if (req.headers['if-none-match'] === etag) {
    res.status(304).end(); // 资源未修改
  } else {
    res.set('ETag', etag);
    res.send(content);
  }
});

app.listen(3000, () => console.log('Server running on port 3000'));

客户端

  • 首次请求:
GET /resource HTTP/1.1
  • 再次请求:
GET /resource HTTP/1.1
If-None-Match: "686897696a7c876b7e"

总结

特性说明
定义资源的唯一标识符
作用缓存控制、条件请求、并发控制
类型强 ETag、弱 ETag
生成方式哈希值、版本号
优点减少带宽消耗、提高性能、支持并发控制
缺点计算开销、隐私问题、缓存失效问题

ETag 是 HTTP 协议中重要的缓存和条件请求机制,合理使用 ETag 可以提高 Web 应用的性能和资源利用率。

更多vue相关插件及后台管理模板可访问vue admin reference,代码详情请访问github