以tomcat为例,浏览器和tomcat之间通过如下几个head来控制是否从服务器端获取资源文件还是之间从浏览器cache中去取
Last-Modified/If-Modified-Since,ETag/If-None-Match
下面通过实验的方式直观的看这几个head是如何工作的,首先创建一个demo项目,然后创建一个html文件和一个js文件用来测试(1.html引用1.js)
下面是第一次访问的截图,可以看到1.html和1.js都返回了200,因为这是第一次访问
然后看下1.js的http的head信息如下图
因为是第一次访问,request head里面没有跟cache有关的信息,但是可以看到response head里面有Last-Modified和ETag
下面在访问的时候,request里面就会携带与Last-Modified/Etag对应的HttpRequestHeader:If-Modified-Since和If-None-Match,如下图
关于If-Modified-Since,tomcat会把这个时间与服务器上实际文件的最后修改时间进行对比。如果时间一致,那么返回304,客户端就直接使用本地缓存文件。如果时间不一致,就会返回200和新的文件内容。客户端接到之后,会丢弃旧文件,把新文件缓存起来,并显示在浏览器中
关于If-None-Match,服务器把这个值和资源的ETag值比较看是否改变,如果变了,则返回200和新的文件内容
其实http协议里面是有专门的协议来控制200(from cache)的,就是Cache-Control: max-age=秒 和 Expires,我们可以通过如下的filter来实现js文件的过期时间为1minute
<filter> <filter-name>ExpiresFilter</filter-name> <filter-class>org.apache.catalina.filters.ExpiresFilter</filter-class> <init-param> <param-name>ExpiresByType image</param-name> <param-value>access plus 1 minutes</param-value> </init-param> <init-param> <param-name>ExpiresByType text/css</param-name> <param-value>access plus 10 minutes</param-value> </init-param> <init-param> <param-name>ExpiresByType application/javascript</param-name> <param-value>access plus 1 minutes</param-value> </init-param> </filter> <filter-mapping> <filter-name>ExpiresFilter</filter-name> <url-pattern>/*</url-pattern> <dispatcher>REQUEST</dispatcher> </filter-mapping>
重启tomcat后,访问1.html,一分钟之内就算update 了 1.js文件,浏览器也会忽略他,直接200(from cache)
如下图,
可以看到time是0,
对应的http head如下,
就是max-age为60起的作用
可是在我测试的时候偶尔会发现有200(from cache)这样的status出现(在我没有用ExpireFilter的时候),无论是Firefox还是chrome这种状态说明浏览器没有发起请求,直接用local的cache,甚至我已经修改了后台的js文件,有时候还是会出现200(from cache),这个可能是浏览器的某些算法擅自认为这个文件在服务器端没有被更新而之间用本地的cache
贴一段google来的话,如下
这个结论不是很准确,实际上这个问题答案全部都在https://tools.ietf.org/html/rfc7234
简单说一下
浏览器的缓存机制分为两块,也就是规范中的4.2. Freshness 和 4.3. Validation
Freshness
Cache Control与Expires是一组,他们是用来进行Freshness验证,也就是提供客户端检测文件是否足够新鲜,可以无需向服务端发起Validation请求就能保证并未过期可以直接使用。
所有的from cache的请求实际上都是由于浏览器认为本地的缓存资源足够新鲜,所以无需额外请求而直接使用。
具体的判断方法可以参考协议,实际上就是根据本地的时间和服务器返回头的约定信息进行对比验证。
历史问题
为何有两个参数而不是一个参数则是由于历史原因,在HTTP1.0中定义的是Expires,Expires的值是一个明确的过期时间,而后来使用中发现一旦客户端时间与服务器时间不一致就会引发很多缓存问题。
因此在HTTP 1.1中新添加了Cache Control,实现了更优的文件过期声明,比如max-age配置,是一个timespan,告知客户端这个文件多长时间不会过期而不是直接告知过期时间。
Validation
Last-Modified和ETag则是另一组控制信息,他们用来实现Validation。他们的职责是在本地缓存被浏览器判断可能不够新鲜的时候,会用这两组信息向服务器请求数据,如果服务器内容没有改变,那么约定服务器会返回304 HTTP Code表明这个缓存可以直接使用,无需重新拉取,而一旦服务器内容改变了就会返回200,同时返回新的文件内容。
历史问题
至于为何有两组字段来解决这个问题依然是历史问题,在HTTP 1.0中约定的是Last-Modified,他代表的含义是文件最后一次修改的时间,那么这种约定带来的问题是一旦内容是动态生成的,这个时间在服务器端不一定可以正确的生成,其次是Last-Modified只有秒级的精度,如果在一秒内有一次以上的文件修改,这样的缓存就会造成额外的问题。
因此HTTP1.1中新引入了ETag,他的实现不尽相同,对于动态内容,常规做法是对动态内容做HASH计算,作为ETAG返回,对于静态资源,一般是使用inode+mtime进行计算。
额外的问题
ETag也有他自己的问题,所以经常在使用中会关闭ETag。举例来说,同一个文件在不同物理机上的inode是不同的,这就导致了在分布式的Web系统中,当访问落在不同的物理机上时会返回不同的ETag,进而导致304失效,降级为200请求。解决办法也有从ETag算法中剥离inode,只是使用mtime,但是这样实际上和Last-Modified就一样了。当然你也可以额外的做一些改进,使ETag对静态资源的算法也是通过hash计算的。不过由于一般我们会使用CDN技术,因此集群部署中的ETag问题并不会造成太大的影响,所以折腾的人也不太是很多。
总结
总结一下,ETag的设置并不会影响Freshness验证,Freshness验证会和浏览器策略以及Cache Control与Expires有关。
ps:https://stackoverflow.com/questions/1665082/http-status-code-200-cache-vs-status-code-304
https://developer.yahoo.com/performance/rules.html#expires=
如果有一个2M的js文件需要做到200(from cache)的话,首先可以让他10年不过期,用这个配置access plus 10 years,然后给js命名bundle.0.2.0.js,这样下次build的时候html就应该引入bundle.0.2.1.js这样之前的文件自然就失效了
相关推荐
本文将详细介绍浏览器缓存机制的工作原理、 Memory Cache、Disk Cache、 HTTP Cache 三种缓存机制的区别和应用场景,以及强缓存和协商缓存的机制。 Memory Cache Memory Cache 是浏览器在内存中存储的缓存,主要...
在这个特定的场景下,我们关注的是“Loadrunner负载测试中的浏览器缓存设置”。了解如何在LoadRunner中正确设置浏览器缓存对于获取真实用户行为的数据至关重要,因为这直接影响到测试结果的准确性。 浏览器缓存是...
HTTP+JS+浏览器缓存技术 浏览器缓存是指浏览器在本地磁盘上存储的静态资源文件,包括HTML、CSS、JavaScript、图片等,以便下一次请求时可以直接从缓存中读取,从而提高网站性能和浏览器速度。浏览器缓存机制可以...
### 浏览器缓存目录设置 在日常的网络浏览过程中,浏览器缓存的作用非常重要,它不仅能够提高网页加载速度,还能有效减少硬盘碎片的产生,进而提升整体系统的运行效率。本文将详细介绍如何针对不同浏览器(如Fire...
浏览器缓存是网络浏览的重要组成部分,它帮助用户快速加载先前访问过的网页,通过存储静态资源如图片、JavaScript和CSS文件,减少对服务器的请求。本文将深入探讨浏览器缓存的工作原理,以及如何使用“浏览器缓存...
在JSP页面中可以通过设置HTTP响应头来实现去除浏览器缓存的目的。下面介绍几种常见的方法: ##### 1. 使用JSP内置对象`response` 在JSP页面中可以直接通过`response`对象来设置HTTP响应头,从而实现去除缓存的目标...
### 浏览器HTTP缓存机制详解 #### 一、概述 HTTP缓存机制是现代Web应用中的一个重要组成部分,它能够显著提升用户体验并减轻服务器负载。本文将详细探讨浏览器HTTP缓存的工作原理及其背后的机制。 #### 二、HTTP...
同时,Service Worker技术也是现代浏览器缓存的重要组成部分,它允许开发者更精细地控制离线缓存和预加载策略。 理解并合理利用这些机制,可以有效地减少网络传输,提升用户体验。例如,设置合适的缓存策略可以减少...
关闭IE10或IE11,再重新打开,浏览器输入上面的网址,可以看到浏览器重定向到http://www.baidu.com,同时控制台还是没有输出,则此时301请求依然被浏览器缓存。 若是chrome浏览器或IE8,新打开TAB页,浏览器会缓存...
1、【合并视频.exe】可将UC浏览器缓存或下载的Y2hlbmppbmdjb25n加密或非加密视频文件合并成mp4视频的工具。 2、使用示例:https://img-blog.csdnimg.cn/0a29f18018c246ebbe70efb82f72c288.png 该示例图可以复制链接...
浏览器缓存【2024年浏览器缓存/HTTP缓存机制(面试常考)简介】 内容概要: 这篇博客为网络技术初学者提供了一个全面的理解浏览器缓存和HTTP缓存机制的指南。通过通俗易懂的语言,本博客介绍了浏览器缓存的工作原理...
浏览器缓存 浏览器缓存主要可以分为两大类:客户端缓存和服务端缓存。客户端缓存,即浏览器缓存,是本文主要讨论的内容。而服务端缓存则主要包括代理服务器缓存和反向代理服务器缓存,以及广泛使用的CDN等。这些...
浏览器缓存策略是HTTP协议中的一种机制,旨在提高网页加载速度和降低服务器负载。通过缓存,浏览器可以在用户再次访问同一网页时,直接从本地存储中读取之前下载的资源,而不是每次都向服务器请求。Httpwatch是一款...
### 清除浏览器缓存的方法及原理 #### 一、背景介绍 在现代互联网应用中,浏览器缓存机制被广泛采用以提升用户体验和减少网络流量消耗。然而,在某些情况下(如开发测试阶段或网站更新后),我们需要清除浏览器...
通过通俗易懂的语言,本博客介绍了浏览器缓存的工作原理,HTTP缓存控制字段,缓存策略的应用,以及面试中可能遇到的关于缓存的问题和实战演练。此外,还探讨了缓存的高级话题,如缓存头字段、缓存与性能的关系,以及...
例如,设置Cache-Control为`no-cache`或`no-store`可以防止浏览器缓存页面,`must-revalidate`则要求每次请求都验证资源是否更新。 2. **HTML5的Service Worker**:Service Worker是一种在浏览器后台运行的脚本,它...
接下来是“浏览器缓存脑图文件”,它可能更直观地呈现了各种缓存策略、缓存验证方法以及HTTP头部字段之间的关系。在这个脑图中,我们可以看到如何通过ETag(实体标签)和Last-Modified(最后修改时间)进行协商缓存...
为了防止这种情况,可以通过设置HTTP响应头来禁止浏览器缓存当前页面。以下是三种常用的响应头字段: 1. `Expires`: 这个字段用来设置一个远期的日期,当该日期过去后,浏览器会认为资源已经过期,从而重新向服务器...
综上所述,浏览器缓存问题的解决需要综合考虑多个方面,包括但不限于HTTP缓存策略的合理设置、缓存污染的预防、个性化内容的安全处理、磁盘空间的有效管理和跨域资源共享的安全控制。通过上述措施的应用,可以有效...
浏览器缓存机制、Expires策略(http1.0)和Cache-control策略(http1.1)、Last-Modified/If-Modified-Since、ETag/If-None-Match