对比(协商)缓存
比较一下再去决定是用缓存还是重新获取数据,这样会减少网络请求,提高性能。
对比缓存的工作原理
客户端第一次请求服务器的时候,服务器会把数据进行缓存,同时会生成一个缓存标识符,这个缓存标识符会被发送到客户端,客户端第二次请求服务器的时候,会把缓存标识符发送到服务器,服务器会根据缓存标识符进行判断,如果缓存标识符相同,则服务器会判断缓存是否过期,如果没有过期,则服务器会返回 304,告诉客户端使用缓存,如果缓存标识符不同,则服务器会返回 200,同时返回新的数据。
- 客户端:
if-modified-since
- 服务端:
Last-Modified
对比最后的修改时间返回内容
缺点是内容没变化修改时间变化了也会重新读取内容,时间不精确,(精确到秒),如果一秒内改了多次也监控不到。
下面我们通过判断文件的修改时间是否对的上,一样的话直接返回 304 告诉读取缓存
新建 cache.js
文件
const http = require("http");
const fs = require("fs");
const path = require("path");
const url = require("url");
const server = http.createServer((req, res) => {
const { pathname } = url.parse(req.url);
const filePath = path.join(__dirname, pathname);
console.log(pathname);
res.setHeader("Cache-Control", "no-cache");
// 第二次请求会带上 if-modified-since 请求头
let ifModifiedSince = req.headers["if-modified-since"];
fs.stat(filePath, (err, statObj) => {
if (err) return res.end();
let lastModified = statObj.ctime.toGMTString();
// 判断文件的修改时间是否对的上,一样的话直接返回 304 告诉读取缓存
if (ifModifiedSince && lastModified === ifModifiedSince) {
res.statusCode = 304;
return res.end();
}
res.setHeader("Last-Modified", lastModified);
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.html
和 style.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
我们修改 style.css
文件,背景改成 pink,然后刷新访问,我们可以看到状态码变成 200,读取到了新的资源
body {
background-color: pink;
}