强制缓存
对于强制缓存来说,响应header中有两个字段来标明失效规则(expires/cache-control)
expires
expires的值为服务器返回的到期时间,下一次请求的时候,请求时间小于服务器返回的时候,直接使用缓存数据。
cache-control
cache-control的常见取值
- private: 客户端可以缓存 (默认值)
- public: 客户端和代理服务器都可以缓存 (对前端来说,private 和 public 是一样的)
- max-age=xxx: 缓存在xxx秒后失效
- no-cache: 需要使用对比缓存来验证缓存数据
- no-store: 所有内容都不会缓存,强制缓存和对比缓存都不会触发
如果有服务器同时设置了expires和cache-control,那么就根据先进的设置cache-control来为标准
对比缓存
对比缓存,就是需要进行对比来判断是否可以使用缓存。浏览器第一次请求数据的时候,服务器会将缓存标识与数据一起返回给客户端,客户端将两者的备份存储在数据库中。
对比缓存,缓存标识在请求header和响应header间进行传递。一共分两种标识传递:
Last-Modified/If-Modified-Since
Last-modified: 服务器在响应请求时,告诉浏览器资源的最后修改时间。
If-modified-Since: 再次请求服务器时,通过此字段通知服务器上次请求时,服务器返回的资源最后修改时间。
若资源的最后修改时间大于Last-Modified-Since 说明资源有被改动过,返回状态码200;若资源的最后修改时间小于或者等于Last-Modified-Since,说明资源没有被修改过,则相应状态码304,告知浏览器继续使用保存的cache。
Etag/If-None-Match(优先级高于Last-Modified/If-Modified-Since)
第一次请求服务器的时候,服务器会将资源和Etag:1234同时告诉给客户端,这个标签是1234,如果修改了资源,我这边的标签就不一样了,。
再次请求服务器的时候,客户端就会带有If-None-Match这个标签。服务器就根据判断这个标签Etag是否更改而返回304或者200的标识。
各种刷新
- 浏览器中写地址,回车
- F5
- Ctrl+F5
假设对一个资源:
浏览器第一次访问,获取资源内容和cache-control: max-age:600,Last_Modify: Wed, 10 Aug 2013 15:32:18 GMT于是浏览器把资源文件放到缓存中,并且决定下次使用的时候直接去缓存中取了。
浏览器url回车
浏览器发现缓存中有这个文件了,好了,就不发送任何请求了,直接去缓存中获取展现。(最快)
下面我按下了F5刷新
F5就是告诉浏览器,别偷懒,好歹去服务器看看这个文件是否有过期了。于是浏览器就胆胆襟襟的发送一个请求带上If-Modify-since:Wed, 10 Aug 2013 15:32:18 GMT
然后服务器发现:诶,这个文件我在这个时间后还没修改过,不需要给你任何信息了,返回304就行了。于是浏览器获取到304后就去缓存中欢欢喜喜获取资源了。
但是呢,下面我们按下了Ctrl+F5
这个可是要命了,告诉浏览器,你先把你缓存中的这个文件给我删了,然后再去服务器请求个完整的资源文件下来。于是客户端就完成了强行更新的操作...
还有说一下,那个ETag实际上很少人使用,因为它的计算是使用算法来得出的,而算法会占用服务端计算的资源,所有服务端的资源都是宝贵的,所以就很少使用etag了。