Http浏览器缓存 ETag,Cache-Control,Expires,Last-Modified,if-none-match,if-modified-since 各自是什么作用

HTTP头部字段 ETag, Cache-Control, Expires, Last-Modified, If-None-Match, 和 If-Modified-Since 都是为了管理和控制HTTP缓存机制而设计的。下面我将逐一解释它们的作用:

1. ETag (Entity Tag)

  • 定义:ETag 是一个由服务器生成的字符串,用来唯一标识一个资源的具体版本。
  • 用途:当浏览器或代理服务器收到一个带有 ETag 的资源后,会在后续请求中使用 If-None-Match 头部来检查该资源是否已被修改。
  • 示例
    • 服务器响应头:
      ETag: "123456"
      
    • 浏览器再次请求时会携带:
      If-None-Match: "123456"
      

2. Cache-Control

  • 定义Cache-Control 是一个非常强大的头部,它可以控制缓存行为,包括缓存的存储、有效性以及重验证等。
  • 用途
    • 定义资源的缓存策略,例如是否允许缓存、缓存多久、何时需要重新验证等。
    • 控制客户端和中间缓存的行为。
  • 示例
    • 允许缓存,但要求在300秒后进行重新验证:
      Cache-Control: max-age=300, must-revalidate
      
    • 不允许任何缓存:
      Cache-Control: no-store, no-cache, must-revalidate
      

3. Expires

  • 定义Expires 指定了资源被认为“过期”的时间点。
  • 用途:如果一个资源在指定的时间之前未发生改变,那么中间缓存就可以直接使用缓存副本,而无需向服务器验证。
  • 示例
    Expires: Thu, 01 Sep 2023 12:00:00 GMT
    

4. Last-Modified

  • 定义Last-Modified 指示了资源最后一次被修改的时间。
  • 用途:浏览器或代理服务器可以通过 If-Modified-Since 请求头来询问服务器资源是否自从某个特定时间之后被修改过。
  • 示例
    • 服务器响应头:
      Last-Modified: Tue, 01 Aug 2023 12:00:00 GMT
      
    • 浏览器再次请求时会携带:
      If-Modified-Since: Tue, 01 Aug 2023 12:00:00 GMT
      

5. If-None-Match

  • 定义If-None-Match 是一个条件请求头,用于验证资源是否与之前收到的版本相同。
  • 用途:如果资源的 ETag 与请求中的 If-Not-Match 匹配,则服务器返回 304 Not Modified 响应,否则返回最新的资源。
  • 示例
    If-None-Match: "123456"
    

6. If-Modified-Since

  • 定义If-Modified-Since 是一个条件请求头,用于询问资源是否自从指定的时间之后被修改过。
  • 用途:如果资源自从指定的时间之后没有被修改过,则服务器返回 304 Not Modified 响应,否则返回最新的资源。
  • 示例
    If-Modified-Since: Tue, 01 Aug 2023 12:00:00 GMT
    

egg demo

function md5(str) {
  return crypto.createHash('md5').update(str).digest('hex')
}

async download() {
    const { ctx } = this;
    const { token } = ctx.query;
    if (!token || token.toString().indexOf('.') > -1) {
      ctx.body = {
        code: 1,
        msg: '参数错误'
      }
      return;
    }
    const filePath = path.join(__dirname, '../uploads', token);
    if (!fs.existsSync(filePath)) {
      ctx.body = {
        code: 1,
        msg: '文件不存在'
      }
      return;
    }
    // 读取图片文件
    const metadata = fs.statSync(filePath);

    // 设置强制缓存
    ctx.set('Cache-Control', 'public, max-age=31536000'); // 公共缓存,有效期一年
    ctx.set('Expires', new Date(Date.now() + 31536000 * 1000).toUTCString()); // 过期时间为一年后

    // 设置协商缓存
    let etag = null;
    if (metadata) {
      etag = `"${md5(metadata.mtime.toUTCString())}"`;
    }
    ctx.set('ETag', etag);
    ctx.set('Last-Modified', metadata.mtime.toUTCString());

    // 处理协商缓存
    if (ctx.request.header['if-none-match'] === etag ||
      ctx.request.header['if-modified-since'] === metadata.mtime.toUTCString()) {
      ctx.status = 304; // 发送 304 Not Modified
    } else {
      ctx.type = metadata.type;
      ctx.body = fs.readFileSync(filePath);
    }
  }

总结

  • ETag 和 If-None-Match:提供了更精确的资源版本控制,适合用于动态内容的缓存管理。
  • Last-Modified 和 If-Modified-Since:适用于较简单的场景,例如静态资源,它们依赖于最后修改的时间戳。
  • Cache-Control 和 Expires:控制缓存的有效期,Cache-Control 更加灵活和强大,而 Expires 则是一个更旧的标准。

在实际应用中,通常会结合使用这些头部以达到最优的缓存效果。例如,使用 ETagIf-None-Match 进行精确的资源版本控制,同时使用 Cache-Control 来设置缓存策略。

  • 7
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值