在Express.js中,可以通过设置响应头来实现缓存控制。为了理解缓存控制的实现方式,我们需要了解两个重要的概念:ETag和Last-Modified。
- ETag(实体标签):ETag是一个用于标识资源版本的标签。服务器会为每个资源生成一个唯一的ETag,并在每个响应中发送给客户端。客户端可以在请求中的
If-None-Match
标头 中将上一次收到的ETag发送回服务器。服务器可以比较这两个ETag值,以确定资源是否有新的版本可用。如果两个ETag匹配,表示资源没有变化,服务器可以返回一个304 Not Modified
的响应,告诉客户端使用缓存版本。 - Last-Modified(最后修改时间):服务器会在响应中发送一个
Last-Modified
标头,指示资源的最后修改时间。客户端可以在后续请求中的If-Modified-Since
标头 中将上一次收到的最后修改时间发送回服务器。服务器可以比较这两个最后修改时间,以确定资源是否有新的修改。如果最后修改时间相同,表示资源没有变化,服务器可以返回一个304 Not Modified
的响应。
下面是一个示例,展示了如何使用ETag和Last-Modified来实现缓存控制:
app.get('/api/data', (req, res) => {
// 假设这是一些动态生成的数据
const data = generateData();
// 设置ETag和Last-Modified响应头
const lastModified = new Date().toUTCString();
const etag = generateETag(data);
res.set('Last-Modified', lastModified);
res.set('ETag', etag);
// 检查客户端发送的If-None-Match和If-Modified-Since标头
const ifNoneMatch = req.get('If-None-Match');
const ifModifiedSince = req.get('If-Modified-Since');
// 如果ETag和If-None-Match匹配,发送304 Not Modified响应
if (ifNoneMatch === etag) {
return res.sendStatus(304);
}
// 如果Last-Modified和If-Modified-Since相同,发送304 Not Modified响应
if (ifModifiedSince && new Date(ifModifiedSince) >= new Date(lastModified)) {
return res.sendStatus(304);
}
// 返回数据
res.json(data);
});
在上面的例子中,我们使用res.set()
方法设置了响应头Last-Modified
和ETag
,分别对应最后修改时间和实体标签。然后,我们获取请求中的If-None-Match
和If-Modified-Since
标头,并与服务器生成的ETag和最后修改时间进行比较。
如果客户端发送的ETag与服务器生成的ETag匹配,或者客户端发送的最后修改时间大于等于服务器的最后修改时间,服务器将返回一个304 Not Modified
的响应。
这样,通过使用ETag和Last-Modified来进行缓存控制,可以减少网络流量,提高应用程序的性能和响应速度。