Node实现浏览器缓存

原理

当浏览器第一次向服务端发送请求时,服务端会返回一个带有Last-Modified: Sat, 02 Dec 2017 04:03:14 GMT字段的响应头,该字段表明所请求的文件最新修改时间;当浏览器下一次向服务端发送请求时,请求头会带上 If-Modified-Since: Sat, 02 Dec 2017 04:03:14 GMT字段,该字段的值是上一次服务器 Last-Modified 返回的值,服务器接收到请求后会根据 If-Modified-Since 值进行判断,如果该值小于服务器文件的值则返回新的文件,否则就告诉浏览器使用缓存文件。
举个例子,当浏览器第一次请求时
在这里插入图片描述
在这里插入图片描述
当浏览器第二次发送请求时
在这里插入图片描述

在这里插入图片描述

思路

  • 服务器对浏览器请求的请求头if-modified-since进行判断,若不存在,则发送文件以及请求头Last-Modified,说明该文件的修改时间
  • 若存在请求头if-modified-since,将请求头if-modified-since的值与文件修改时间进行比较
  • 如果请求头if-modified-since的值小于文件修改时间,则发送文件以及请求头Last-Modified,说明该文件的修改时间
  • 如果请求头if-modified-since的值等于或大于文件修改时间,则返回304状态码,告知浏览器读取缓存文件

实例

没有实现缓存时:
在这里插入图片描述

此时每次请求服务器都会重新发送文件(观察状态码)

实现缓存之后:
在这里插入图片描述

const http=require('http');
const fs=require('fs');
const url=require('url');

http.createServer( (req, res) => {
  let {pathname} = url.parse(req.url);

  // 获取文件日期
  fs.stat(`.${pathname}`, (err, stat) => {
    if(err) {
      res.writeHeader(404);
      res.write('Not Found');
      res.end();
    }else {
      if (req.headers['if-modified-since']) {
        // 浏览器 if-modified-since 字段值
        let oDate = new Date(req.headers['if-modified-since']);
        let time_client = Math.floor(oDate.getTime() / 1000);
        
        // 服务端文件最新修改时间
        let time_server = Math.floor(stat.mtime.getTime() / 1000);

        if (time_client < time_server) {
          // 浏览器缓存文件的修改时间小于服务端文件修改时间,发送文件
          sendFileToClient();
        }else {
          // 浏览器缓存文件的修改时间等于或大于服务器文件的修改时间
          // 发送 304 状态码,告知浏览器从缓存中读取数据
          res.writeHeader(304);
          res.write('Not Modified');
          res.end();
        }

      }else {
        // 浏览器是第一次请求该文件,不存在 if-modified-since 字段
        // 从服务器端读取文件
        sendFileToClient();
      }

      function sendFileToClient() {
        let rs = fs.createReadStream(`.${pathname}`);

        // 设置请求头 Last-Modified 字段,值为该文件最新修改时间
        res.setHeader('Last-Modified', stat.mtime.toGMTString());

        // 输出
        rs.pipe(res);

        rs.on('error', err => {
          res.writeHeader(404);
          res.write('Not Found');
          res.end();
        });
      }
    }
  })
}).listen(1337);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值