为什么要使用cache?
往往我们在请求完一次后,再想请求同样的内容,我们不想再从服务端获取,而是从第一次访问的时候保存下来的数据请求,这样有利于减少访问时间、降低网络负荷。
ok,我们知道需求以后,就得看下Cache有哪些东西。
http缓存相关头
1.Expires (实体标头,HTTP 1.0+)
一个GMT时间,试图告知客户端,在此日期内,可以信任并使用对应缓存中的副本,缺点是,一但客户端日期不准确.则可能导致失效.
2.Pragma : no-cache(常规标头,http1.0+)
对Pragma定义的唯一的伪指令,同http1.1的Cache-Control : no-cache
- Last-Modified(实体标头,HTTP1.0+)
一个GMT时间,告知,被请求实体的最后修改时间.用于客户端校验其缓存副本是否仍然可以信任.与其相关的两个条件请求标头:
- If-Modified-Since:(此标头,仅对Get方法有意义)
如果实体在指定时间后,没有修改则返回一个304,否则返回一个常规的Get请求的响应(比如200).
另外,如果该标头的值是一个非法的值,那么也同样返回一个常规的Get请求的响应.PS:用户代理发起
If-Modified-Since尝试握手的条件,可能会有不同,比如IE系,如果该实体第一次响应头中包含Cache-Control:no-cache.则
IE不会使用If-Modified-Since请求资源.而其他浏览器则会.
但是如果使用Cache-Control:no-store.则所有用户代理的表现一致.都不使用If-Modified-Since(因为no-store的语义十分强烈.不允许任何缓存,这个在后续有专门介绍.)
- If-Unmodified-Since:
如果实体在指定时间后,没有任何修改,那么就可以直接执行该请求使用方法的对应行为. 而如果有修改,则返回一个412 Precondition
Failed状态码,并且抛弃该方法对应的行为操作(GET方法除外).
3.Cache-Control : (常规标头,HTTP1.1)
- public:(仅为响应标头)
响应:告知任何途径的缓存者,可以无条件的缓存该响应.
- private(仅为响应标头)
响应:告知缓存者(据我所知,是指用户代理,常见浏览器的本地缓存.用户也是指,系统用户.但也许,不应排除,某些网关,可以识别每个终端用户的情况),只针对单个用户缓存响应.
且可以具体指定某个字段.如private –“username”,则响应头中,名为username的标头内容,不会被共享缓存.
- no-cache:
请求:
告知缓存者,必须原原本本的转发原始请求,并告知任何缓存者,别直接拿你缓存的副本,糊弄人.你需要去转发我的请求,并验证你的缓存(如果有的话).对应名词:端对端重载.响应: 允许缓存者缓存副本.那么其实际价值是,总是强制缓存者,校验缓存的新鲜度.一旦确认新鲜,则可以使用缓存副本作为响应.
no-cache,还可以指定某个包含字段,比如一个典型应用,no-cache=Set-Cookie.
这样做的结果,就是告知缓存者,对于Set-Cookie字段,你不要使用缓存内容.而是使用新滴.其他内容则可以使用缓存.
- no-store:
请求:告知,请求和响应都禁止被缓存.(也许是出于隐私考虑) 响应:同上.
- max-age:
请求:强制响应缓存者,根据该值,校验新鲜性.即与自身的Age值,与请求时间做比较.如果超出max-age值,则强制去服务器端验证.以确保返回一个新鲜的响应.其功能本质上与传统的Expires类似,但区别在于Expires是根据某个特定日期值做比较.一但缓存者自身的时间不准确.则结果可能就是错误的.而max-age,显然无此问题.
Max-age的优先级也是高于Expires的. 响应:同上类似,只不过发出方不一样.
- max-stale:
请求:意思是,我允许缓存者,发送一个,过期不超过指定秒数的,陈旧的缓存. 响应:同上.
- must-revalidate(仅为响应标头)
响应:意思是,如果缓存过了新鲜期,则必须重新验证.而不是试图返回一个不在新鲜期的缓存.与no-cache的区别在于,no-cache,完全无视新鲜期的概念.总是强制重新验证.理论上,must-revalidate更节省流量,但相比no-cache,可能并不总是那么精准.因为即使缓存者,认为是新鲜的,也不能保证服务器端没有做过更新.如果缓存者是一个缓存代理服务器,如果其试图重新验证时,无法连接上原始服务器,则也不允许返回一个不新鲜的,缓存中的副本.而是必须返回一个504
Gateway timeout.
- proxy-revalidate(仅为响应标头)