You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JS fetch能否基于ETag缓存不同URL的相同数据?

可以仅依赖ETag忽略URL实现缓存,需手动接管部分缓存逻辑

浏览器默认缓存机制以最终请求URL为核心标识,所以每次重定向到新的唯一URL时,浏览器会判定为全新资源,不会复用之前的缓存。但你可以通过手动管理ETag并配合请求头设置,让缓存逻辑优先依赖ETag而非URL:

  • 第一步:存储ETag与资源内容
    首次请求完成后,从响应头提取ETag值,同时把返回的资源内容存入localStorage、sessionStorage或IndexedDB中,示例代码:

    fetch('你的原请求URL')
      .then(res => {
        const etag = res.headers.get('ETag');
        if (etag) localStorage.setItem('target-etag', etag);
        return res.text();
      })
      .then(content => {
        localStorage.setItem('target-content', content);
        // 后续业务逻辑处理
      });
    
  • 第二步:后续请求携带ETag验证
    之后每次发起请求时,带上存储的ETag,同时通过Cache-Control: no-cache强制服务器验证资源是否更新:

    const savedEtag = localStorage.getItem('target-etag');
    const savedContent = localStorage.getItem('target-content');
    
    fetch('你的原请求URL', {
      headers: {
        ...(savedEtag && { 'If-None-Match': savedEtag }),
        'Cache-Control': 'no-cache'
      }
    })
    .then(res => {
      if (res.status === 304) {
        // 服务器确认资源未变更,直接使用本地存储的内容
        return Promise.resolve(savedContent);
      } else {
        // 资源已更新,重新存储新的ETag和内容
        const newEtag = res.headers.get('ETag');
        if (newEtag) localStorage.setItem('target-etag', newEtag);
        return res.text().then(newContent => {
          localStorage.setItem('target-content', newContent);
          return newContent;
        });
      }
    })
    .then(content => {
      // 处理最新资源内容
    });
    
  • 关键前提
    服务器必须正确支持If-None-Match头的验证逻辑:当收到带ETag的请求时,对比当前资源的ETag值,若一致则返回304 Not Modified,而非每次都返回200状态码和完整内容。

另外注意ETag类型:带W/前缀的弱ETag会判断资源语义是否相同,强ETag则要求字节完全一致,可根据业务场景选择适配。

内容的提问来源于stack exchange,提问作者zino

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 07:25:31