---
title: ETag强弱校验与缓存一致性治理(W/前缀/条件请求)最佳实践
keywords:
- ETag
- 条件请求
- If-None-Match
- 强/弱ETag
- 一致性
description: 通过强/弱ETag策略与条件请求校验、统一生成规则与变更策略,保障缓存一致性与减少不必要传输。
categories:
- 文章资讯
- 编程技术
---
背景与价值
ETag允许客户端进行条件请求与缓存验证。合理生成与校验可减少传输并保持一致性。
统一规范
- 弱ETag:使用
W/"..."对内容近似变化使用弱校验。 - 强ETag:对内容完全一致使用强校验。
- 条件请求:支持
If-None-Match与304响应。
核心实现
ETag生成与校验
function b64url(buf: ArrayBuffer): string { const u = new Uint8Array(buf); let s=''; for (let i=0;i<u.length;i++) s+=String.fromCharCode(u[i]); return btoa(s).replace(/\+/g,'-').replace(/\//g,'_').replace(/=+$/,'') }
async function etagWeak(body: ArrayBuffer): Promise<string> { const d = await crypto.subtle.digest('SHA-256', body); return 'W/"' + b64url(d) + '"' }
async function etagStrong(body: ArrayBuffer): Promise<string> { const d = await crypto.subtle.digest('SHA-256', body); return '"' + b64url(d) + '"' }
function matchAny(inm: string | undefined, tag: string): boolean { const s = (inm || '').split(',').map(t => t.trim()); return s.includes(tag) }
条件请求响应
type Req = { headers: Record<string, string | undefined> }
type Res = { setHeader: (k: string, v: string) => void; status: (n: number) => Res; end: (b?: any) => void }
async function serve(body: ArrayBuffer, req: Req, res: Res, weak = true) {
const tag = weak ? await etagWeak(body) : await etagStrong(body)
res.setHeader('ETag', tag)
const inm = req.headers['if-none-match']
if (matchAny(inm, tag)) return res.status(304).end()
res.end(body)
}
落地建议
- 为静态与动态资源分别选择强/弱ETag并支持条件请求,减少带宽并保持一致性。
- 与缓存策略协同(Cache-Control/immutable)实现高效验证与长效缓存。
验证清单
- 是否生成并下发强/弱ETag;条件请求命中是否返回304。

发表评论 取消回复