缓存(Cache)是计算机领域里的一个重要概念,是优化系统性能的利器。
服务器的缓存控制
1.浏览器发现缓存无数据,于是发送请求,向服务器获取资源;
2.服务器响应请求,返回资源,同时标记资源的有效期;
3.浏览器缓存资源,等待下次重用。
服务器标记资源有效期使用的头字段是“Cache-Control”,里面的值“max-age=30”就是资源的有效时间,相当于告诉浏览器,“这个页面只能缓存 30 秒,之后就算是过期,不能用。”
时间的计算起点是响应报文的创建时刻(即 Date 字段,也就是离开服务器的时刻),而不是客户端收到报文的时刻,也就是说包含了在链路传输过程中所有节点所停留的时间。
客户端的缓存控制
你可以在 Chrome 里点几次“刷新”按钮,估计你会失望,页面上的 ID 一直在变,根本不是缓存的结果,明明说缓存 30 秒,怎么就不起作用呢?
其实不止服务器可以发“Cache-Control”头,浏览器也可以发“Cache-Control”,也就是说请求 - 应答的双方都可以用这个字段进行缓存控制,互相协商缓存的使用策略。
当你点“刷新”按钮的时候,浏览器会在请求头里加一个“Cache-Control: max-age=0”。服务器看到 max-age=0,也就会用一个最新生成的报文回应浏览器。
那么,浏览器的缓存究竟什么时候才能生效呢?别着急,试着点一下浏览器的“前进”“后退”按钮,再看开发者工具,你就会惊喜地发现“from disk cache”的字样,意思是没有发送网络请求,而是读取的磁盘上的缓存。
重定向跳转功能,也可以发现浏览器使用了缓存。
在“前进”“后退”“跳转”这些重定向动作中浏览器不会“夹带私货”,只用最基本的请求头,没有“Cache-Control”,所以就会检查缓存,直接利用之前的资源,不再进行网络通信。
条件请求
验证资源是否失效需要使用“条件请求”,常用的是“if-Modified-Since”和“If-None-Match”,收到 304 就可以复用缓存里的资源;
验证资源是否被修改的条件有两个:“Last-modified”和“ETag”,需要服务器预先在响应报文里设置,搭配条件请求使用;浏览器也可以发送“Cache-Control”字段,使用“max-age=0”或“no_cache”刷新数据。