赞
踩
浏览器缓存
通过 Cache-Control 以及 max-age 设置,达到长缓存的效果。
启动服务器 node server.js,在 localhost:8888 打开,查看network,当设置 max-age 后,刷新页面,浏览器直接从缓存中进行读取,不去要再向服务器请求,达到缓存静态资源的目的。
存在的问题,服务端修改返回内容,客户端没有加载新的内容,因为请求 url 没变,浏览器会直接从缓存读取,不需要经过服务端验证,导致静态资源更新后,没有及时更新到客户端。
解决方案,打包静态资源时,根据内容进行 hash 计算,生成文件名的 hash 码。内容变,hash 码变,请求资源 url 变,浏览器重新请求加载资源,达到更新缓存的目的。
// 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') { response.writeHead(200, { 'Content-Type': 'text/javascript', 'Cache-Control': 'max-age=200' // 浏览器缓存时间 }) response.end('console.log("script loaded twice")') } }).listen(8888) console.log('server listening on 8888')
// test.html
<script src="/script.js"></script>
max-age可以接收很多值,如 ‘Cache-Control’: ‘max-age=200, public’
Last-Modified
Etag
上次修改时间。
配合If-Modified-Since或If-Unmodified-Since使用,通常浏览器使用前者。
服务器对比上次修改时间以验证资源是否需要更新。
数据签名,资源内容会对应有一个唯一的签名,如果资源数据更改,签名也会变。
配合If-Match或者If-None-Match使用,其值就是服务端返回的 Etag 值
对比资源的签名判断是否使用缓存
服务器设置 Last-Modifed 和 Etag 的值,浏览器请求会携带这两个头,在请求头中,会有 If-Modified-since: Last-Modifed值 和 If-None-Match: Etag值。
这时 response 中是有内容的,这里希望服务器不返回实际的内容,只需要告诉浏览器直接读取缓存即可。通过在服务器端进行判断。
这时查看 respones 发现还是有内容,这个内容是 Chrome 浏览器 从缓存中读取显示出来的,服务器没有返回内容。
如何判断服务端通过验证,但是从缓存读取的呢,通过服务器设置 HTTP Code 304,Not Modified 表示资源没有修改,直接读缓存,这时就会忽略服务端返回的内容。
Chrome 浏览器 控制台 勾上 Disable cache,刷新页面,发送的请求中就不包括和缓存相关的头了
// 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') { console.log(request.headers) 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', // 通过 no-cache,即使没过期浏览器也要向服务器验证,不会从缓存读取。 'Last-Modified': '123', // 随便设的值 'Etag': '777' }) response.end('console.log("script loaded twice")') } } }).listen(8888) console.log('server listening on 8888')
// test.html
<script src="/script.js"></script>
不从缓存读取
'Cache-Control': 'max-age=2000000, no-cache', // 通过 no-cache,即使没过期浏览器也要向服务器验证,不会从缓存读取。
设置 no-store,即使服务器下发了缓存相关头,浏览器也会忽略任何和缓存相关的信息,发送请求不会携带相关头,直接去请求最新的数据。
Chrome浏览器->右上角->更多工具->清理浏览器缓存
'Cache-Control': 'max-age=2000000, no-store'
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。