正文ETag(实体标签)是 HTTP 条件请求的核心。强 ETag 适用于字节级一致性判断,弱 ETag 适用于语义一致但字节可能不同的场景(例如:相同数据经不同格式化)。本文给出强/弱 ETag 的生成与 `If-None-Match`、`If-Modified-Since` 的协同治理实践。一、强/弱 ETag 生成方法// app/api/etag/route.ts export const runtime = 'edge' async function strongETag(input: ArrayBuffer) { const digest = await crypto.subtle.digest('SHA-256', input) const bytes = new Uint8Array(digest) let b64 = '' for (let i = 0; i < bytes.length; i++) b64 += String.fromCharCode(bytes[i]) return '"sha256-' + btoa(b64) + '"' } function weakETag(size: number, mtimeMs: number) { return `W/"${size}-${mtimeMs}"` } 二、条件请求与 304 响应治理优先使用 ETag 校验,其次使用 `Last-Modified` 与 `If-Modified-Since`。始终在 304 响应中回显当前的标准化响应头(ETag/Last-Modified/Cache-Control),确保中间缓存层的一致性。export async function GET(req: Request) { // 示例资源:真实场景可来自存储/渲染结果 const body = new TextEncoder().encode('Hello ETag v2') const lastModified = new Date('2025-11-01T00:00:00Z') const strong = await strongETag(body.buffer) const weak = weakETag(body.byteLength, lastModified.getTime()) const inm = req.headers.get('if-none-match') || '' const ims = req.headers.get('if-modified-since') // 优先 ETag 校验;兼容强/弱标签 if (inm && (inm.includes(strong) || inm.includes(weak))) { return new Response(null, { status: 304, headers: { ETag: strong, 'Last-Modified': lastModified.toUTCString(), 'Cache-Control': 'public, max-age=60, s-maxage=300, must-revalidate' } }) } // 次选 Last-Modified 校验 if (ims) { const imsDate = new Date(ims) if (!Number.isNaN(imsDate.getTime()) && imsDate.getTime() >= lastModified.getTime()) { return new Response(null, { status: 304, headers: { ETag: strong, 'Last-Modified': lastModified.toUTCString(), 'Cache-Control': 'public, max-age=60, s-maxage=300, must-revalidate' } }) } } // 命中失败:返回资源与标准缓存头 return new Response(body, { headers: { 'Content-Type': 'text/plain; charset=utf-8', ETag: strong, 'Last-Modified': lastModified.toUTCString(), 'Cache-Control': 'public, max-age=60, s-maxage=300, stale-while-revalidate=600', 'Vary': 'Accept-Encoding' } }) } 三、选型建议与注意事项强 ETag:适合静态资源、经过完整哈希的产物(如构建输出),确保字节级一致。弱 ETag:适合语义一致但字节可能不同的场景(JSON 序列化差异、空白字符变化),提高命中率但不用于 Range 请求合并。回显策略:在 304 响应中始终回显当前 ETag 与 Last-Modified,避免中间层状态偏差。`Vary` 管理:仅在必要的协商维度(如 `Accept-Encoding`、`Accept`、UA-CH)设置 `Vary`,防止缓存分片过度导致命中率下降。安全与一致性:为动态生成内容设置合理的 `max-age/s-maxage` 与 `must-revalidate`/`stale-while-revalidate`,避免过时内容长尾污染。四、扩展:HEAD 与弱标签策略对于目录索引或列表页,可提供 `HEAD` 路由快速探测并返回 ETag/Cache-Control,不携带响应体,降低探测带宽与耗时。弱标签可用于允许“轻微变更但视为未变”场景,需结合业务语义评估适配度。

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论
立即
投稿

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部
1.814885s