前段时间优化项目,设计到需要缓存静态文件的问题,静下心来了解了下浏览器的缓存机制。
首先,不知道大家注意到没有,HTTP请求的一下参数
此处,为第一次请求
response Headers 里面注意几个参数
Expries:是HTTP 1.0的东西,现在默认浏览器均默认使用HTTP 1.1,所以它的作用基本忽略。
Etag:web服务器响应请求时,告诉浏览器当前资源在服务器的唯一标识(生成规则由服务器决定)。Apache中,ETag的值,默认是对文件的索引节(INode),大小(Size)和最后修改时间(MTime)进行Hash后得到的。优先级高于cache-control
Last-Modified:最后修改时间
cache-control:Cache-Control与Expires的作用一致,优先级高于Expires。都是指明当前资源的有效期,控制浏览器是否直接从浏览器缓存取数据还是重新发请求到服务器取数据
Cache-Control | 可以设置的值 |
Public | 响应可被任何缓存区缓存。 |
private |
对于单个用户的整个或部分响应消息,不能被共享缓存处理。 这允许服务器仅仅描述当用户的部分响应消息,此响应消息对于其他用户的请求无效。 |
no-cache | 请求或响应消息不能缓存 |
no-store | 防止重要的信息被无意的发布。在请求消息中发送将使得请求和响应消息都不使用缓存。 |
max-age | 客户机可以接收生存期不大于指定时间(以秒为单位)的响应。 |
min-fresh | 客户机可以接收响应时间小于当前时间加上指定时间的响应 |
max-stale |
指示客户机可以接收超出超时期间的响应消息。 如果指定max-stale消息的值,那么客户机可以接收超出超时期指定值之内的响应消息。 |
Expries,cache-control 用来检测内容是否过期,需不需要重新请求HTTP。
Last-Modified,Etag是检测内容是否发生变化,是否需要重新返回文件。
下面我们重新刷新,看下请求发生了什么变化
第二次请求request 里面多了2个字段
If-Modified-Since:当资源过期时,发现资源具有Last-Modified声明,则再次向web服务器请求时带上头 If-Modified-Since,表示请求时间。web服务器收到请求后发现有头If-Modified-Since 则与被请求资源的最后修改时间进行比对。若最后修改时间较新,说明资源又被改动过,则响应整片资源内容(写在响应消息包体内),HTTP 200;若最后修改时间较旧,说明资源无新修改,则响应HTTP 304 (无需包体,节省浏览),告知浏览器继续使用所保存的cache。
If-None-Match:当资源过期时(使用Cache-Control标识的max-age),发现资源具有Etage声明,则再次向web服务器请求时带上头If-None-Match (Etag的值)。web服务器收到请求后发现有头If-None-Match 则与被请求资源的相应校验串进行比对,决定返回200或304。
Last-Modified/If-Modified-Since
Last-Modified/If-Modified-Since要配合Cache-Control使用。
Etag/If-None-Match
Last-Modified/If-Modified-Since要配合Cache-Control使用。
Last-Modified 和 Etag一起使用,优先使用Etag ,那么为什么有了last-Modified ?(HTTP1.1中Etag的出现主要是为了解决几个Last-Modified比较难解决的问题:)
1.Last-Modified标注的最后修改只能精确到秒级,如果某些文件在1秒钟以内,被修改多次的话,它将不能准确标注文件的修改时间因此,HTTP/1.1利用Entity Tag头提供了更加严格的验证。
2.如果某些文件会被定期生成,当有时内容并没有任何变化,但Last-Modified却改变了,导致文件没法使用缓存
3.有可能存在服务器没有准确获取文件修改时间,或者与代理服务器时间不一致等情形
Etag是服务器自动生成或者由开发者生成的对应资源在服务器端的唯一标识符,能够更加准确的控制缓存。Last-Modified与ETag是可以一起使用的,服务器会优先验证ETag,一致的情况下,才会继续比对Last-Modified,最后才决定是否返回304。
缓存和用户操作行为有关
以上是浏览器的缓存机制