强缓存
Expires
const http = require('http');
const url = require('url');
const path = require('path');
const fs = require('fs');
http.createServer((req, res) => {
const {pathname} = url.parse(req.url, true); // parse的第二个参数表示解析query参数
console.log(pathname);
const abs = path.join(__dirname, pathname);
res.setHeader('Expires', new Date(Date.now() + 120000).toGMTString()); // 设置强缓存有效时间为120秒
fs.stat(path.join(__dirname, pathname), (err, stat) => {
if(err) {
res.statusCode = 404;
res.end('not found');
return;
}
if(stat.isFile()) {
fs.createReadStream(abs).pipe(res);
}
})
}).listen(3000, () => {
console.log('Server is running at 3000');
});
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
如下图所示:首次请求,返回200 ok,直接从服务器拿资源。
120s内刷新当前页面,直接从内存里面加载对应资源。因为没有关闭当前的tab页,所以浏览器直接从内存缓存中加载。
120s内关闭当前tab页,在新的tab页重新打开请求的url,浏览器直接从磁盘缓存中加载。关闭了tab页,内存缓存也随之清空。但是磁盘缓存是持久的,于是资源来自磁盘缓存。需要注意:内存缓存还是比disk cache快得多的。
120s以后请求,强缓存已经失效,重新从服务器拿资源,同时更新Expires响应头。
Cache-Control
// server.js
const Koa = require('koa');
const path = require('path');
const static = require('koa-static');
const app = new Koa();
const port = 8089;
app.use(async (ctx, next) => {
// 设置响应头Cache-Control,设置资源有效期为100秒
ctx.set({'Cache-Control': 'max-age=100'});
await next();
});
app.use(static(path.join(__dirname, './static')));
app.listen(port, () => {
console.log(`Server is running at ${port}`);
});
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
刷新页面可以看到响应头的Cache-Control变成了max-age=100。
三级缓存原理验证
我们刚进行了网络请求,浏览器把git_diff.png存进了磁盘和内存中。根据三级缓存原理,我们会先在内存中找资源,我们来刷新页面。
如上图所示:200 OK(from memory cache)
,符合预期。
接下来,关掉该页面,再重新打开。因为内存是存在进程中的,所以关闭该页面,内存中的资源也被释放掉了,磁盘中的资源是永久性的,所以还存在。 根据三级缓存原理,如果在内存中没找到资源,便会去磁盘中寻找!
如上图所示:200 OK(from disk cache)
,符合预期,以上也就验证了三级缓存原理。
我们刚对资源设置的有效期是100秒,我们接下来来验证缓存是否失效。100秒后。。。
如上图所示,缓存失效了。
协商缓存
Cache-Control的默认值就是no-cache(需要进行协商缓存,发送请求到服务器确认是否使用缓存。),所以我们这里不用对Cache-Control进行设置。
// ETag support for Koa responses using etag.
yarn add koa-etag -D
// etag works together with conditional-get
yarn add koa-conditional-get -D
2
3
4
Etag
// server.js
const Koa = require('koa');
const path = require('path');
const static = require('koa-static');
const conditional = require('koa-conditional-get');
const etag = require('koa-etag');
const app = new Koa();
const port = 8089;
app.use(conditional());
app.use(etag());
app.use(static(path.join(__dirname, './static')));
app.listen(port, () => {
console.log(`Server is running at ${port}`);
});
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
如上图所示:第一次请求,我们发现返回值里面已经有了Etag值。 接下来再请求的时候,浏览器将会带上If-None-Match请求头,并赋值为上一次返回头的Etag值,然后与 这次返回值的Etag值进行对比。如果一致则命中协商缓存。返回304 Not Modified。接下来我们来验证一下:
ok,如图所示,完美验证了上面的说法。
接下来我们修改git_diff.png(图片名称没有变化,但是图片内容发生改变了),来验证是否资源改变时,协商缓存策略也就失效呢?
如图所示:协商缓存失败,重新进行了资源请求,并返回新的Etag值。