美文网首页
http缓存

http缓存

作者: 成熟稳重的李先生 | 来源:发表于2019-10-29 23:47 被阅读0次

http缓存分为两种, 强制缓存(网站首页不能做缓存)和对比缓存。

// cache.js
let http = require("http")
let mimie = require("mime"); //第三方模块,用于添加content-type
let url = require("url");
let path = require("path");
let fs = require("fs");
/ *
  * 首页的html文件可以使用对比缓存
  * 第一次访问的时候,设置一个头, “last-modified”--最后的修改时间
  * 下次在请求的时候,带上这个时间,看是否一致
  */
http
  .createServer((req, res) => {
    let { pathname } = url.parse(req.url, true);
    let absPath = path.join(__dirname, pathname);
    // js,css文件之类的, 每次更改了,就要重新请求,-----这是对比缓存

 /*
  * 强制缓存(如果服务器上文件修改了,但是每到缓存失效的时间,
  * 那么浏览器端不会更新,因此强制缓存是有局限性的)
  * 这种缓存只针对像js,css,img这类的文件
  */
   res.setHeader("Cache-Control", "max-age=5"); //相对时间,单位是秒
   res.setHeader("Expires", new Date(Date.now() + 5000).toUTCString());  // 绝对时间

    fs.stat(absPath, (err, statObj) => {
      if (err) {
        res.statusCode = 404;
        res.end(`Not Found`);
      }
      if (statObj.isFile()) {
         let ctime = statObj.ctime.toUTCString();
     /*
      * 对比缓存分两种:
      * 1). last-modified(最后修改时间)
     */
      /*
       * if-modified-since是浏览器自己携带的,
       * 如果服务器设置过last-modified,那么下次请求就会带上“if-modified-since
       * 缺陷:1)如果文件没变,但是时间改了
       *  2) 时间精确到秒,可能会有问题
       */

        if (req.headers["if-modified-since"] == ctime) {  // 如果时间没变,设置304
           res.statusCode = 304;
           res.end();
           return;
         }
        res.setHeader("Last-Modified", ctime);  //最后修改时间
   /*
    * 2). Etag(摘要)
    * Etag的方式比较靠谱,但是不能对大文件进行摘要文件Etag,可以采用“文件大小+文件的最后修改时间”来组成Etag
    */
        let md5 = crypto.createHash("md5");
        let rs = fs.createReadStream(absPath);
        let arr = []; //要先写入响应头,再写入响应体
        rs.on("data", function(data) {
          md5.update(data);
          arr.push(data);
        });
        rs.on("end", () => {
          let etag = md5.digest("base64");
        // "if-none-match"和"Etag"是一对,响应头如果设置了“Etag”,那么请求会带上“if-none-match”
       // 两者进行对比,得出是否需要走缓存
          if (req.headers["if-none-match"] === etag) {
            res.statusCode = 304;
            res.end();
            return;
          }
          res.setHeader("Etag", etag);
          res.end(Buffer.concat(arr));
        });

        res.setHeader("Content-Type", mime.getType(absPath) + ";charset=utf-8");
        fs.createReadStream(absPath).pipe(res);
      }
// 一般情况下,这两种缓存都使用,访问服务器时,会先加一个强制缓存,强制缓存n秒
// n秒过后,会在发送请求时使用对比缓存,先判断last-modified和if-modified-since,Etag和if-none-match,
// 如果都成立,则返回304,再强制缓存n秒
// 如果有变化,返回新的文件
// 304 = last-modified + if-modified-since  和 Etag + if-none-match(强制缓存不属于304)
    });
  })
  .listen(3000);

相关文章

  • HTTP缓存原理

    什么是HTTP缓存 HTTP缓存通常指浏览器缓存,基于HTTP中header字段实现HTTP缓存分为强缓存和协商缓...

  • 前端缓存

    前端缓存 前端缓存主要是分为HTTP缓存和浏览器缓存。其中HTTP缓存是在HTTP请求传输时用到的缓存,主要在服务...

  • 前端缓存详解

    一、前言 前端缓存主要是分为HTTP缓存和浏览器缓存。其中HTTP缓存是在HTTP请求传输时用到的缓存,主要在服务...

  • PWA笔记一:Web的万物基础缓存

    前言 这里讨论的缓存包括两种,一种是HTTP缓存,一种是Service Worker缓存。 HTTP缓存 HTTP...

  • 前端缓存的理解 或者 前端数据持久化的理解(强制缓存、协商缓存)

    前端缓存分为HTTP缓存和浏览器缓存 其中HTTP缓存是在HTTP请求传输时用到的缓存,主要在服务器代码上设置;而...

  • http缓存和各个版本差异理解

    http缓存我们可以通过设置http头部属性来对资源进行缓存,资源缓存分为强制缓存和协商缓存 强制缓存expire...

  • http缓存

    http缓存分为强制缓存和对比缓存 强制缓存时, 客户端先判断本地缓存是否有效(http/1.1通过Cache-C...

  • HTTP缓存

    缓存控制Cache-Control Cache-Control是Web性能优化的一种,能加速HTTP请求与响应。 ...

  • http缓存

    来源: 《http权威指南》学一个东西,怎么去学习呢?这分为三个步骤,是什么, 为什么, 怎么做?文章我会着重讲怎...

  • Http缓存

    参考文章:http://oohcode.com/2015/05/28/http-cache/ 客户端 头字段: C...

网友评论

      本文标题:http缓存

      本文链接:https://www.haomeiwen.com/subject/pbcnvctx.html