http缓存的故事

上帝说:“来点缓存”。

于是http1.0的响应头有一个Expires字段,设置值为以后的时间,如2020-11-11, 就会缓存到客户端时间的2020年。但是如果客户端时间被修改成2030,缓存就会过期。

于是http1.1的响应头有了一个Cache-Control字段,设置值 max-age=1000,就会缓存1000秒。而且这个1000秒是从你拿到第一个响应开始算的,所以不会受到人为修改时间的影响。要注意就算max-age=0,也是缓存了的,只是立马就过期而已。

老罗说:“缓存过期也没关系,又不是不能用!”。

又不是不能用

于是http1.0的请求头有个 If-Modified-Since,响应头有个Last-Modified。当一个缓存过期了,就带着客户端之前得到的上次修改时间,与服务端的最后一次修改时间作比较,如果时间一致,服务端就会发出“304,304,又不是不能用”的声音。如果服务端的修改时间较新,就会返回新的值并让客户端继续缓存。但是如果服务端的那个文件只是打开又关上,修改时间也变了,其实它还是它,不应该重新发送。

于是http1.1的请求头有个 If-None-Match ,响应头有个Etag,大致功能跟上面一样,只是这个Etag相当于文件的hash值,就算移动几次都不会认为是新文件。

上帝说:“不要搞缓存那一套,我想一直跟服务器谈笑风生”。

于是http1.1有了 Cache-Control: no-store 这种键值对。

http1.0说自己也可以,只要 Pragma: no-cache 就行。但是http1.1跟他说,老哥,你这样其实是跟我的 Cache-Control: no-cache 一样, 并不是完全不存。

我说:“我们的首页可以这样实现缓存”。

我刚开始觉得,首页不应该缓存,每次都去拿新的首页才好,反正也不大。转念一想,我可以让它 max-age=0,先缓存着,这样每次再请求的时候,缓存都是过期的,但是过期又不是不能用,我就带着if-modified-since或者if-none-match去服务器问一下,要是服务器告诉我,老哥,304。我立马回来,直接从浏览器里拿了。如果不是304,我就从服务器拿,这样也能保证我每次都是拿到最新的,而且少了很多不必要的数据传输。但是每次写max-age=0太烦了,于是就改成了 Cache-Control: no-cahe。这也就是http1.0的Pragma: no-cache。

理解万岁。