我来为您讲解 “Node强缓存和协商缓存实战示例”的攻略。
强缓存
强缓存是指在缓存数据时,客户端直接使用缓存,而不再发起请求。要使用强缓存,需要设置响应头中的 Cache-Control
或 Expires
。
Cache-Control
通过设置 Cache-Control
为 max-age
或 s-maxage
可以实现强缓存。其中,max-age
是基于客户端本地时间的缓存时间,单位是秒,而 s-maxage
则是为代理缓存设置的缓存时间。例如:
Cache-Control: max-age=3600
这样,当第一次请求服务器时,服务器返回了数据,并在响应头中设置了 Cache-Control: max-age=3600
,那么在一小时内,客户端直接使用本地缓存,并不再次请求服务器。
Expires
Expires
是设置过期缓存的时间,单位为 GMT 格式的时间字符串。例如:
Expires: Thu, 29 Apr 2021 08:22:23 GMT
与 Cache-Control
的区别在于,Expires
是基于服务器时间的,而 Cache-Control
是基于客户端本地时间的。
协商缓存
如果强制缓存无法满足要求,而需要每次发送请求时都与服务器进行一次交互,就可以使用协商缓存。协商缓存需要客户端将缓存标识发送给服务器,由服务器根据缓存标识进行判断是否命中缓存。
Last-Modified 和 If-Modified-Since
在请求头中加入 If-Modified-Since
字段,值为上一次的 Last-Modified
时,如果文件的修改时间跟 If-Modified-Since
中的时间一致,则返回 304 状态码,表示缓存未失效。例如:
If-Modified-Since: Thu, 29 Apr 2021 08:22:23 GMT
服务端需要在返回数据的同时,设置 Last-Modified
字段,值为该内容的最后修改时间。例如:
Last-Modified: Thu, 29 Apr 2021 08:22:23 GMT
ETag 和 If-None-Match
在服务端返回的响应头种加入 ETag
字段,用于标识版本号。客户端再次请求时,在请求头中带上上次的 ETag
值,服务端比对,如果一致,则返回 304 状态码。例如:
ETag: "12345"
客户端请求头中的 If-None-Match
字段可设置上次请求返回的 ETag
值。例如:
If-None-Match: "12345"
实例说明
以下是两个实战示例:
示例一:使用强缓存
const http = require('http');
const fs = require('fs');
const path = require('path');
http.createServer(function (req, res) {
const filePath = path.join(__dirname, 'index.html');
const stat = fs.statSync(filePath);
const fileContent = fs.readFileSync(filePath);
const lastModified = stat.mtime.toUTCString();
res.setHeader('Cache-Control', 'max-age=3600');
res.setHeader('Last-Modified', lastModified);
const ifModifiedSince = req.headers['if-modified-since'];
if (ifModifiedSince && ifModifiedSince === lastModified) {
res.writeHead(304, 'Not Modified');
res.end();
} else {
res.setHeader('Content-Length', Buffer.byteLength(fileContent));
res.writeHead(200, 'OK');
res.end(fileContent);
}
}).listen(3000);
console.log('Http Server is running on port 3000.');
这里使用了强缓存,设置了 Cache-Control
的值,当文件未修改时,直接返回 304 状态码。如果文件重写,则会请求最新的文件。
示例二:使用协商缓存
const http = require('http');
const fs = require('fs');
const path = require('path');
http.createServer(function (req, res) {
const filePath = path.join(__dirname, 'index.html');
const stat = fs.statSync(filePath);
const fileContent = fs.readFileSync(filePath);
const lastModified = stat.mtime.toUTCString();
const etag = `"${stat.size}-${stat.mtime.getTime()}"`;
res.setHeader('Cache-Control', 'no-cache');
res.setHeader('Last-Modified', lastModified);
res.setHeader('ETag', etag);
const ifModifiedSince = req.headers['if-modified-since'];
const ifNoneMatch = req.headers['if-none-match'];
if (ifNoneMatch === etag) {
res.writeHead(304, 'Not Modified');
res.end();
} else {
res.setHeader('Content-Length', Buffer.byteLength(fileContent));
res.writeHead(200, 'OK');
res.end(fileContent);
}
}).listen(3000);
console.log('Http Server is running on port 3000.');
这里使用了协商缓存,设置了 Last-Modified
和 ETag
,当文件未修改时,直接返回 304 状态码,如果文件重写,则会请求最新的文件。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:node强缓存和协商缓存实战示例 - Python技术站