71 # 协商缓存的配置:通过内容

对比(协商)缓存

比较一下再去决定是用缓存还是重新获取数据,这样会减少网络请求,提高性能。

对比缓存的工作原理

客户端第一次请求服务器的时候,服务器会把数据进行缓存,同时会生成一个缓存标识符,这个缓存标识符会被发送到客户端,客户端第二次请求服务器的时候,会把缓存标识符发送到服务器,服务器会根据缓存标识符进行判断,如果缓存标识符相同,则服务器会判断缓存是否过期,如果没有过期,则服务器会返回 304,告诉客户端使用缓存,如果缓存标识符不同,则服务器会返回 200,同时返回新的数据。

上一节使用了修改时间的方式,这一节用内容来处理

使用 md5 摘要算法:不是加密算法(不可逆)

  • 不可逆
  • 不同内容转化的结果不相同
  • 转化后的结果都是一样长的
  • 同样的东西产生的结果肯定是相同的
  • 雪崩效应,一点不同翻天覆地不同

使用的库是 crypto 这个库

const crypto = require('crypto');
console.log(crypto.createHash('md5').update('kaimo313').digest('base64'));
// rFDqro5Lox3vFXr5fA4r7Q==
  • 客户端:if-none-match
  • 服务端:ETag 当前文件唯一标识

ETag + if-none-match 可以实现对比缓存,比较的方式比较精准,缺点是文件很大性能就很差,但是默认我们不会完整内容生成 hash 戳,可以取文件的某一部分,为了保证精确度,可采用内容的一部分加上文件的总大小来生成 hash 戳,这样性能会好很多。

新建 cache.js

const http = require("http");
const fs = require("fs");
const path = require("path");
const url = require("url");

const crypto = require("crypto");

const server = http.createServer((req, res) => {
    
    
    const {
    
     pathname } = url.parse(req.url);
    const filePath = path.join(__dirname, pathname);
    console.log(req.headers);
    res.setHeader("Cache-Control", "no-cache");
    // 拿到客户端传过来的 if-none-match 文件标识
    let ifNoneMatch = req.headers["if-none-match"];

    fs.stat(filePath, (err, statObj) => {
    
    
        if (err) return res.end();
        // 进行文件摘要产生hash
        let contentHash = crypto.createHash("md5").update(fs.readFileSync(filePath)).digest("base64");
        if (ifNoneMatch === contentHash) {
    
    
            res.statusCode = 304;
            return res.end();
        }
        res.setHeader("ETag", contentHash);
        // 第一请求,需要根据内容生成一个唯一的标识:可以对应当前的文件
        if (err) return (res.statusCode = 404), res.end("Not Found");
        // 判断是否是文件
        if (statObj.isFile()) {
    
    
            fs.createReadStream(filePath).pipe(res);
        } else {
    
    
            res.statusCode = 404;
            res.end("Not Found");
        }
    });
});
server.listen(5000);

然后新建 public 文件夹,里面添加 index.htmlstyle.css

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>凯小默测试对比缓存:通过内容</title>
</head>

<body>
    <link rel="stylesheet" href="/public/style.css">
</body>

</html>
body {
    
    
    background-color: seagreen;
}

我们启动服务,访问 http://127.0.0.1:5000/public/index.html,可以看到第二次请求的资源变成了 304

nodemon cache.js

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/kaimo313/article/details/132353640
71
71A