缓存头Cach-Control的含义及使用
读取缓存
1、特性
'Cach-Control' : 'max-age=200, public' // 多个设置时,逗号分隔
-
可缓存性
public http经过的任何地方都能进行缓存
private 只有发起请求的浏览器才可以进行缓存
no-cache 本地是可以缓存的,但使用缓存需要经过服务器验证 -
到期
max-age = < seconds > 缓存到多少秒之后过期,max-age = 20
s-maxage = < seconds > 可以代替上面那个,但是只有在代理服务器里面才会生效
max-stale = < seconds > 在max-age过期之后,在max-stale过期之前仍然可以使用过期的max-age时间内的缓存,只在请求发起端设置有用,服务器返回设置无用
注意点:
- 如果服务器改变,客户端还是请求原缓存的内容,会导致数据更新不及时,解决方法,在js文件名上增加一个哈希值,如果内容改变,js名称变更,达到浏览器更新缓存的过程
- 浏览器只识别max-age,如果在代理服务器中同时存在,会选择s-maxage
-
重新验证(基本也不怎么用到)
must-revalidate 在max-age到期之后,必须去原服务端验证是否过期重新获取缓存
proxy-revalidate 缓存服务器 -
其他
no-store 本地和代理服务器都不能使用缓存
no-transform 告诉代理服务器,不允许随便改动或转换服务器返回的内容
对代理服务器设置的一些头,只是限制但是代理服务器可以不按这个来
缓存验证 Lat-Modified和Etag
1、浏览器发出一个请求查找缓存的一个过程
2、验证头
// 设置no-cache,表示使用缓存前需要服务器验证
'Cach-Control' : 'max-age=200, no-cache',
'last-Modified': '123',
'Etag': '777'
-
Last-Modified
上次修改时间
配合 If-Modified-Since 或 If-Unmodeified-Since 使用,使用 If-Modified-Since 的值对比资源存在的地方,是否有修改
对比上次修改时间以验证资源是否需要更新 -
Etag
更加严格的验证,数据签名,
配合If-Match或If-None-Match使用
对比资源的签名判断是否使用缓存当我们设置了Last-Modified 、Etag,浏览器请求头会携带对应的If-Modified-Since、If-None-Match,可以用来判断
nodejs服务器代码示例
const etag = request.headers['if-none-match'];
if(etag === '777'){
response.writeHead(304, {
'Content-Type':'text/javascript',
'Cache-Control': 'max-age=200000000, no-cache',
'Last-Modified':'123',
'Etag': '777'
})
response.end('')
} else {
response.writeHead(200, {
'Content-Type':'text/javascript',
'Cache-Control': 'max-age=200000000, no-cache',
'Last-Modified':'123',
'Etag': '777'
})
response.end('console.log("script loaded")')
}
cookie、session
cookie
- 通过Set-Cookie设置
- 下次请求会自动带上
- 键值对,可以设置多个
属性:
max-age 和 expires 设置过期时间
Secure只在https的时候发送
HttpOnly无法通过document.cookie访问,安全性,防止注入性脚本攻击
注意点:
- cookie没有设置过期时间,关闭浏览器就清空了
- max-age表示多长时间后过期, expires 表示到什么时间点过期,效果一样的,max-age相对简单一点
// cookie id过期时间是2秒
// abc 无法通过document.cookie访问,也就是说禁止javascript访问cookie
'Set-Cookie': ['id=123;max-age=2','abc=456;HttpOnly']
// 可以通过host根据不同域名来增加cookie(代码是node.js)
const host = request.headers.host
if(host === 'a.test.com'){
response.writeHead(200, {
'Content-Type':'text/html',
// 不能跨域设置cookie
'Set-Cookie': ['id=123;max-age=2','abc=456;']
})
}
session
- session不等于cookie
- session和cookie不是一一对应的,不一定要由cookie实现,可以通过js的方式写在header里也可以实现
- cookie session一般配合使用,比如用户id直接存cookie不安全