# 缓存验证 Last-Modified 和 Etag 的使用
如果我们设置了 Cache-Control 设置了 no-cache 之后;那么每次浏览器对已经设置了 Cache-Control 的资源的请求的时候,都要去服务器端进行一个资源的验证,验证完之后,如果确定这个资源可以使用缓存,他才会读取本地的缓存。
# 资源验证
从浏览器发送请求到查找缓存的过程:
# 验证头
- Last-Modified
上次修改时间,配合 If-Modified-Since 或者 If-Unmodified-Since 使用;也就是说如果请求一个资源,这个资源返回的头中包含 Last-Modified 的设置;在下次浏览器发送请求的时候就会带上 Last-Modified 设置以及 If-Modified-Since 或者 If-Unmodified-Since 到服务器,服务器通过读取这两个值;进行对比文件上次修改的时间,如果发现两个时间一样,代表资源没有修改过,服务器就可以告诉浏览器可以使用本地缓存。
- Etag
通过数据签名进行验证数据。就是对资源的内容进行计算,生成一个唯一的标识。配合 If-Match 或者 If-Non-Match 使用;对比资源的签名判断是否使用缓存。
# node 实践
const http = require('http')
const fs = require('fs')
http.createServer(function(req, res) {
if (req.url === '/script.js') {
const html = fs.readFileSync('test.html', 'utf-8')
res.writeHead(200, {
'Content-Type': 'text/javascript',
'cache-Control': 'max-age=20000, no-cache',
'Last-Modified': '123',
'Etag': '888'
})
res.end('console.log("loaded")')
}
}).listen(8888)
可以看到,浏览器再次发送请求,Request Headers 会携带信息:也是服务端返回的数据,浏览器会携带上这些缓存头到服务器验证是否使用缓存。
If-Modified-Since: 123
If-None-Match: 888
在服务器端可以通过缓存头进行判断是否要缓存:
const http = require('http')
const fs = require('fs')
http.createServer(function(req, res) {
if (req.url === '/script.js') {
const etag = req.headers['if-none-match']
if (etag === '888') {
res.writeHead(304, {
'Content-Type': 'text/javascript',
'cache-Control': 'max-age=20000, no-cache',
'Last-Modified': '123',
'Etag': '888'
})
// 这里的返回结果不会再浏览器中返回,是直接使用浏览器中的缓存
res.end('')
} else {
res.writeHead(200, {
'Content-Type': 'text/javascript',
'cache-Control': 'max-age=20000, no-cache',
'Last-Modified': '123',
'Etag': '888'
})
res.end('console.log("loaded")')
}
}
}).listen(8888)
no-store 是没有任何缓存的:会忽略任何跟缓存有关的信息。
const http = require('http')
const fs = require('fs')
http.createServer(function(req, res) {
if (req.url === '/script.js') {
const etag = req.headers['if-none-match']
if (etag === '888') {
res.writeHead(304, {
'Content-Type': 'text/javascript',
'cache-Control': 'max-age=20000, no-store',
'Last-Modified': '123',
'Etag': '888'
})
// 这里的返回结果不会再浏览器中返回,是直接使用浏览器中的缓存
res.end('')
} else {
res.writeHead(200, {
'Content-Type': 'text/javascript',
'cache-Control': 'max-age=20000, no-store',
'Last-Modified': '123',
'Etag': '888'
})
res.end('console.log("loaded")')
}
}
}).listen(8888)
阅读量: