资源验证
如果catche-Ctrol设置了no-cache(任何节点都不可以缓存。可以在本地服务器缓存,每次发起请求都需要去服务器验证,如果服务器说可以使用缓存,才能使用缓存。也就是说需要经过服务器验证的。)
设置了Catche-Ctrol的请求过程如下:

数据如何验证?
1、验证头
-
Last-Modified
上次修改时间。给资源设置了上一次是什么时候被修改的。
配合If-Modified-Since或者If-Unmodified-Since使用。
验证是否可以使用缓存的过程:如果我们请求了一个资源,如果返回的head里面有以上两个头信息,指定了时间,下次在请求的时候就会带上这两个传过来的值到服务器,通常浏览器都是用If-Modified-Since,服务器就可以通过读取head里面的If-Modified-Since的值,然后对比资源存在的地方,对比上次修改时间,如果发现这两个时间是一样的,代表这个资源还没有被修改,服务器就告诉浏览器直接使用缓存。对比上次修改时间以验证资源是否需要更新。 -
Etag
一个更加严格的验证。- 数据签名
一个资源对它的内容会产生一个唯一的签名,如果这个资源进行了修改,这个签名就会变成新的,这样前后的签名就不一样。
典型做法:对内容进行hash计算(就像打包文件一样,对内容计算就会得到一个唯一值)。用来标记这个资源。 - 配合if-Match或者If-Non-Macth使用
下次请求就会带上这两个值,就是服务端返回的Etag值。 - 对比资源的签名判断是否使用缓存
- 数据签名
if (request.url === '/script.js') {
response.writeHead(200, {
'Content-Type': 'text/javascript',
// 设置到期时间 , 每次发起请求都需要去服务器验证
'Cache-Control': 'max-age=20000000000,no-cache',
//Last-Modified
'Last-Modified' : '123',
// Etag
'Etag' : 777
})


这个时候依旧返回了内容,因为内容并没有修改,所以不需要服务器返回response,做法如下:对比Etag
// 如果两次结果相同,返回缓存结果为空
const etag = request.headers['if-none-match']
if(etag === '777'){
response.writeHead(304, {
'Content-Type': 'text/javascript',
'Cache-Control': 'max-age=20000000000,no-cache',
'Last-Modified' : '123',
'Etag' : 777
})
// 设置请求结果为空
response.end('')
}else{
response.writeHead(200, {
'Content-Type': 'text/javascript',
'Cache-Control': 'max-age=20000000000,no-cache',
'Last-Modified' : '123',
'Etag' : 777
})
// 否则就是内容修改了,返回最新结果
response.end('console.log("script loaded twice")')
}

网友评论