cache是一种存储给定资源,当下次有请求时用副本代替重新从服务器拉取源数据的一种技术。一般只有
GET
请求的资源才会被缓存。
主要可以分为两大类:private, shared
- shared 被多个用户共享的cache,第一个请求会到服务器,其他的都直接获取被shared cache,eg: proxy caches
- private 专门给单一用户的cache,每个用户的第一个请求都会到服务器,接下来的会直接使用本地cache, eg: browser caches
1、Cache-control(HTTP/1.1)
- 不缓存: 每个请求都会发送到服务端,每次重新下载资源
Cache-Control: no-store
Cache-Control: no-cache, no-store, must-revalidate
no-cache意思不是do not cache, 而是说在每一次使用cache response之前需要revalidate with server
must-revalidate指当资源被过期之后必须
revalidate
之后才能被使用
- 验证缓存
Cache-Control: no-cache
- 共有和私有缓存
Cache-Control: private // 只会被单个用户缓存,比如浏览器缓存,不会被存为 shared cache
Cache-Control: public // 能被任何缓存机制缓存。在一些不能被缓存的情况下,比如HTTP授权或者非正常可缓存状态码(200, 301),缓存资源
- 过期
Cache-Control: max-age: 31536000 // 设置最大过期时间,相对于请求时间,在缓存静态文件时很有用
2、Pragma(HTTP/1.0)
Pragma: no-cache
和Cache-Control: no-cache
一样作用,可作为其在HTTP/1.0向后兼容的方案。
3、Freshness(过期与否)
缓存驱逐(cache eviction):理论上缓存是能被永久存储的,但是考虑缓存空间是有限制的,所有会有资源定期被从缓存中移除。
有效期限(lifeTime):
-
Cache-Control: max-age: N
N就是有限期限 - 很多情况都没有
max-age
这种设置,这样会去查看是否存在Expires
头,Expire - Date
值就是lifeTime - 如果上面都没有,找
Last-Modify
,(Date - LastModify) / 10
值就是lifeTime
过期时间:
expirationTime = responseTime + freshnessLifetime - currentAge
// currentAge接近于0,会 `Age`头影响
Last-Modified: <day-name>, <day> <month> <year> <hour>:<minute>:<second> GMT
// Last-Modify需要配合 If-Modified-Since/If-None-Match
// Last-Modify通常用来缓存与ETag无关的一些实体
4、缓存验证
点击重新加载按钮或者有Cache-control:must-revalidate
头都会触发revalidation
。而只有提供了强验证器和弱验证器才会验证。
强验证器:当Entity
改变时,哪怕只是1bit的改变,Entity Tag
就会改变时就是Strong validator
弱验证器:当Entity
改变时,但Entity Tag
不一定变化时就是weak validator
在资源过期之后,validator
能让客户端不直接拉取新资源而是在可以在请求头携带特定标识让服务器去验证该资源是否真正失效,如果无效返回200和新的资源,如果还有效则返回304让浏览器继续使用缓存,并更新过期时间。
ETag: W/"<etag_value>"
ETag: "<etag_value>
Etag: "686897696a7c876b7e"
If-None-Match: "686897696a7c876b7e"
ETag
是用来标识特定版本的资源的响应头,客户端是不知道这些标识的含义的(opaque-to-the-useragent),配合
If-None-Match
使用。
Last-Modified
是一种weak validator
,配合If-Modified-Since
或If-Unmodified-Since
网友评论