缓存头Cache-Control的含义和使用
首先Cache-Control有哪些特性呢?一个是可缓存性
可缓存性
public: 代表这个http请求返回的内容所经过的任何路径中,包括一些中间的http的代理服务器,以及发出这个请求的客户端浏览器,他都可以进行这个返回内容的缓存的操作 private: 代表只有发起请求的浏览器才可以进行缓存 no-cache: 任何一个节点都不可以进行缓存
到期
max-age=<seconds>: 多少秒以后过期,再重新请求 s-maxage=<seconds>: 会代替max-age,但是只有代理服务器里面才会生效,也就是浏览器端还是会读取max-age的时间 max-stale=<seconds>: 如果返回过期之后,但是只要在max-stale的时间内,他还是可以使用缓存,而不需要去原服务器里面请求一个新的内容,这个设置只有发起端才有用
重新验证(不太会用到)
must-revalidate: 在设置了max-age,重新发送请求的时候,再重新验证这个内容是否已经真的过期了
proxy-revalidate: 跟must一样的意思,但是是在代理服务器上用的
其他
no-store: 本地和代理服务器都不可以使用缓存,彻底的不能用,但是no-cache经过验证后可能可以使用
no-transform: 主要用在proxy服务器那边,意思是不要随便改动返回的内容,比如压缩,分片等格式转换
这些头只是声明性的作用,他没有任何强制性的约束力,比如设置一些,让代理服务器按照规范去做,但是完全可以不按照规范做
// server.js const http = require('http'); const fs = require('fs'); http.createServer(function(req,res){ console.log('req come', req.url); if (req.url === '/') { const html = fs.readFileSync('test.html', 'utf8'); res.writeHead(200,{ 'Content-Type': 'text/html' }) res.end(html); } if (req.url === '/script.js') { res.writeHead(200,{ 'Content-Type': 'text/javascript' }) res.end('console.log("script loaded")'); } }).listen(8888); console.log('server listening on 8888'); console.log('http://localhost:8888/')
<!--test.html--> <body> <script src='/script.js'></script> </body>
启动server,可以看到script.js已经加载好了,这代表整个都是通过网络传输过来的,现在将max-age设为20s
if (req.url === '/script.js') { res.writeHead(200,{ 'Content-Type': 'text/javascript', 'Cache-Control': 'max-age=20' }) res.end('console.log("script loaded")'); }
可以看到刷新的时候,已经从缓存里面去请求了,这里把js内容改了,如果没到时间,还是读的缓存,没有读取新的js文件,这是因为 url 没变,所以设置了cache-control,只是客户端缓存,直接读取客户端缓存,根本不经过服务端验证,所以服务端更新了文件之后,客户端并不知道服务端已经更新了
我们希望客户端读取的是缓存,但是又不希望服务端内容更新了之后,比如css,image,js。客户端请求的还是老的资源,常见的做法是使用hash码,这个hash码是根据内容生成的一个hash码,如果内容没变,hash不变,如果内容变了,hash也会变,有了变化之后就是一个新的请求
cache-control通过逗号设置不同的值,同类型会从后往前覆盖
'Cache-Control': 'max-age=20,public,private'