缓存
-
Expires
: 绝对时间,比较老 -
Cache-Control
: 相对时间,相对上一次请求的时间,单位:秒。 -
If-Modified-Since
/Last-Modified
:- 浏览器第一次向服务器请求,服务器会返回
Last-Modified
最后修改的时间。 - 浏览器再次向服务器请求,会在 request 头中携带
If-Modified-Since
,值为第一次获取的Last-Modified
,询问自从上一次的最后修改时间到现在,是否再次修改过。如果没改过,就返回304
,如果改变了,发送新的内容,并且再发送一个新的Last-Modified
-
If-None-Match
/ETag
: 服务器每次响应response
会携带一个ETag
,标识文件信息。浏览器每次请求request
会携带If-None-Match
向服务器校验缓存。
- 浏览器第一次向服务器请求,服务器会返回
创建模块 cache.js
// cache.js
const {cache} = require('../config/defaultConfig');
function refreshRes(stats, res) {
const {maxAge, expires, cacheControl, lastModified, etag} = cache;
if (expires) {
res.setHeader('Expires', new Date((Date.now() + maxAge * 1000)).toUTCString());
}
if (cacheControl) {
res.setHeader('Cache-Control', `public, max-age=${maxAge}`);
}
if (lastModified) {
res.setHeader('Last-Modified', stats.mtime.toUTCString());
}
if (etag) {
res.setHeader('ETag', `${stats.size}-${stats.mtime}`);
}
}
module.exports = function isFresh(stats, req, res) {
refreshRes(stats, res);
const lastModified = req.headers['if-modified-since'];
const etag = req.headers['if-none-match'];
/*如果是第一次请求,没有 lastModified 和 etag*/
if (!lastModified && !etag) {
return false;
}
/*如果有 lastModified 但是和原来的不一样*/
else if (lastModified && lastModified !== res.getHeader('Last-Modified')) {
return false;
}
/*如果有 etag 但是和原来的不一样*/
else if (etag && etag !== res.getHeader('ETag')) {
return false;
}
return true;
};
在 defaultConfig.js
模块中添加 cache
属性
const defaultConfig = {
root: process.cwd(),
hostname: '127.0.0.1',
port: 9527,
compressType: /\.(html|css|js|md|json|jpg|jpeg|png)$/,
cache: { //添加 cache 属性
maxAge: 600,
expires: true,
cacheControl: true,
lastModified: true,
etag: true
}
};
module.exports = defaultConfig;
在 route.js
中引用
const isFresh = require('./cache');
/*判断 res 是否新鲜,如果新鲜则返回 304*/
if (isFresh(stats, req, res)) {
res.statusCode = 304;
res.end();
return;
}
浏览器再次访问 url 可以看到 304 状态码。