以前以为HTTP缓存是个简单的事,项目中遇到后才发觉关于缓存实践有挺深的学问。
from几篇文章详见:
使用 HTTP 缓存:Etag, Last-Modified 与 Cache-Control
稍作总结:
整个 Web 系统架构在 HTTP 协议 之上, 利用 HTTP 的缓存机制不仅可以极大地减少服务器负载, 更重要的是加速页面的载入,以及减少用户的流量消耗。 快速到达和易于访问是 Web 与生俱来的特性, 其缓存机制也早已被服务器和浏览器厂商广泛地实现。Web 服务器(比如 Tomcat、Apache、Virgo)或服务器端框架(比如 Django、Express.js) 都会实现 HTTP 缓存机制, 涉及到的 HTTP 头字段注意包括如下:
Cache-Control、Expires、Etag(If-None-Match)、Last-Modified(If-Modified-Since )
Cache-Control :表示资源是否可以被缓存及缓存的有效期
Expires:表示资源被缓存的截止日期
Etag:表示资源的版本,此后浏览器可据此进行缓存及询问服务器
Last-Modified:表示资源的最后修改时间,此后浏览器可据此进行缓存及询问服务器
前两者分别用于设置缓存存活时间长度、截止日期;后两者用于设置资源版本、最后更新时间。
浏览器使用缓存有两种使用情况:
浏览器询问服务器缓存是否有效,服务器返回 304 指示浏览器使用缓存;
资源仍然处于有效期时,浏览器会直接使用磁盘缓存。
缓存设置会导致资源有效性和一致性问题。实践经验:
谨慎地使用过期时间,最好配合 MD5 一起使用。
总是启用条件请求,比如 Etag 或 Last-Modified。
文件服务采用 Last-Modified,动态内容采用 Etag。
分离经常变化的部分,也会提高缓存的命中率。
浏览器刷新行为:
F5或地址栏输入地址会尝试根据Etag或Last-Modified询问服务端是否可以使用缓存;
从超链接或新标签页输入地址访问页面时若缓存仍有效会直接使用磁盘缓存;
CTRL + F5不适用缓存全部从服务端获取最新资源;