通过 http-server分析协商缓存 的原理

查看 http-server 源码
http-server\lib\core\index.js

stat {
ino 索引节点号
mtime:最后一次修改文件的时间
size 以字节为单位的文件容量
}


function statFile() {
// stat 检查文件是否存在 
fs.stat(file, (err, stat) => {
	 // 求 为文件生成 lastModified etag 
     const lastModified = (new Date(stat.mtime)).toUTCString();
      const etag = generateEtag(stat, weakEtags);
      
	// response 返回给浏览器
	res.setHeader('last-modified', lastModified);
    res.setHeader('etag', etag);
	
	if (shouldReturn304(req, lastModified, etag)) {
        status[304](res, next);
        return;
      }
})
}

在这里插入图片描述

在这里插入图片描述
第一次请求头 没有 If-Modified-SinceIf-None-Match 在这里插入图片描述
第二次请求头
多提交了 If-Modified-SinceIf-None-Match
If-None-Match 上次传返回的 etag
If-Modified-Since 上次传返回的 last-modified
根据 stat生成etag,可以看到 etag 中包含了上传修改时间
在这里插入图片描述
第二次请求,lastModified 和 etag 全相等,则返回 304 ,使用协商缓存
1.先 lastModified 和服务器的 serverLastModified比较,如果服务器的 时间大于 提交的时间则不使用协商缓存,表明文件有更新。一般没更新获取到的都是是相等的
// 不是东八区时间,而是国际标准时区
// 东八区格式:Wed Dec 13 2023 17:52:31 GMT+0800

 new Date(Date.parse('Wed, 13 Dec 2023 06:15:31 GMT'))

2.检查 eatg 是否相等

 function shouldReturn304(req, serverLastModified, serverEtag) {
    if (!req || !req.headers) {
      return false;
    }
    const clientModifiedSince = req.headers['if-modified-since'];
    const clientEtag = req.headers['if-none-match'];
    let clientModifiedDate;
    if (!clientModifiedSince && !clientEtag) {
      // Client did not provide any conditional caching headers
      return false;
    }
    if (clientModifiedSince) {
      // Catch "illegal access" dates that will crash v8
      try {
        clientModifiedDate = new Date(Date.parse(clientModifiedSince));
      } catch (err) {
        return false;
      }
      if (clientModifiedDate.toString() === 'Invalid Date') {
        return false;
      }
      // If the client's copy is older than the server's, don't return 304
      if (clientModifiedDate < new Date(serverLastModified)) {
        return false;
      }
    }
    if (clientEtag) {
      // Do a strong or weak etag comparison based on setting
      // https://www.ietf.org/rfc/rfc2616.txt Section 13.3.3
      if (opts.weakCompare && clientEtag !== serverEtag
          && clientEtag !== `W/${serverEtag}` && `W/${clientEtag}` !== serverEtag) {
        return false;
      }
      if (!opts.weakCompare && (clientEtag !== serverEtag || clientEtag.indexOf('W/') === 0)) {
        return false;
      }
    }
    return true;
  }

强制不使用协商缓存,本质都是浏览器不发送 If-Modified-SinceIf-None-Match 字段

  1. ctrl + F5
  2. 禁用缓存
    在这里插入图片描述

参考文献:

https://nodejs.cn/api/fs.html#fsstatpath-options-callback
https://github.com/http-party/http-server
https://juejin.cn/post/6974529351270268958
https://blog.csdn.net/u012294618/article/details/72630092

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值