缓存验证Last-Modified和Etag的使用
介绍
缓存工作示意图:
浏览器创建一个请求,然后请求到达本地缓存,如果找到了则直接返回给浏览器,如果没有,可能会经过代理服务,然后去代理缓存中去找,如果命中,则直接返回,如果没有,才会到源服务器进行请求。
两个验证头
在http协议里面,数据的验证方式,主要有两个验证头:Last-Modified 和 Etag。
Last-Modified 配合Last-Modified-Since或者If-Unmodified-Since使用,对比上次修改的时间验证资源是否需要更新。
Etag 是一个更加严格的数据验证。数据签名[根据数据的内容进行签名,如果数据内容变了,Etag也会变],最典型的Etag数据签名就是hash计算。配合If-Match或者If-Non-Match使用,对比资源的签名判断是否使用缓存。
进行测试
//server.js
const http = require('http')
const fs = require('fs')
http.createServer(function(request, response) {
console.log('request come', request.url)
if(request.url === '/') {
const html = fs.readFileSync('test.html', 'utf8')
response.writeHead(200, {
'Content-Type': 'text/html'
})
response.end(html)
}
if(request.url === '/script.js') {
const html = fs.readFileSync('test.html', 'utf8')
response.writeHead(200, {
'Content-Type': 'text/javascript',
'Cache-Control':'max-age=2000000, no-cache',
'Last-Modified': '123',
'Etag': '777'
})
response.end('console.log("script loaded twice")')
}
}).listen(8888)
console.log('server listening on 8888')
2、重启服务刷新浏览器
3、再刷新浏览器,结果可以看到,它还是去访问了服务器。
它的Requset Headers显示如下
它的repsonse里面是有内容的,的但是我们的内容没有做更改,我们这时只需要告诉浏览器不需要返回实际的内容,只需要去读取缓存就好了。这时我们可以将server.js修改为如下:
const http = require('http')
const fs = require('fs')
http.createServer(function(request, response) {
console.log('request come', request.url)
if(request.url === '/') {
const html = fs.readFileSync('test.html', 'utf8')
response.writeHead(200, {
'Content-Type': 'text/html'
})
response.end(html)
}
if(request.url === '/script.js') {
const html = fs.readFileSync('test.html', 'utf8')
response.writeHead(200, {
'Content-Type': 'text/javascript',
'Cache-Control':'max-age=2000000, no-cache',
'Last-Modified': '123',
'Etag': '777'
})
const etag = request.headers['if-none-match']
if(etag === '777'){
response.writeHead(304, {
'Content-Type': 'text/javascript',
'Cache-Control':'max-age=2000000, no-cache',
'Last-Modified': '123',
'Etag': '777'
})
response.end(' ')
} else {
response.writeHead(200, {
'Content-Type': 'text/javascript',
'Cache-Control':'max-age=2000000, no-cache',
'Last-Modified': '123',
'Etag': '777'
})
}
response.end('console.log("script loaded twice")')
}
}).listen(8888)
console.log('server listening on 8888')
然后再此刷新会看到如下界面,304表示的就是从缓存里面读取内容。如果将上述的no-cache去掉,结果和之前一样,但是如果将no-cache换成no-store,就不会和缓存有任何关系,每次发送请求都会认为那是一个全新的请求,去请求成功,返回200。