`
jag522
  • 浏览: 33865 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

浏览器缓存机制

    博客分类:
  • Web
 
阅读更多

浏览器缓存机制,其实主要就是HTTP协议定义的缓存机制(如:ExpiresCache-control等)。但是也有非HTTP协议定义的缓存机制,如使用HTML Meta 标签,Web开发者可以在HTML页面的<head>节点中加入<meta>标签,代码如下:

html code

<META HTTP-EQUIV="Pragma" CONTENT="no-cache">

 上述代码的作用是告诉浏览器当前页面不被缓存,每次访问都需要去服务器拉取。使用上很简单,但只有部分浏览器可以支持,而且所有缓存代理服务器都不支持,因为代理不解析HTML内容本身。

 

下面我主要介绍HTTP协议定义的缓存机制。

  

Expires策略

 ExpiresWeb服务器响应消息头字段,在响应http请求时告诉浏览器在过期时间前浏览器可以直接从浏览器缓存取数据,而无需再次请求。

 下面是宝宝PK项目中,浏览器拉取jquery.js web服务器的响应头:

 注:Date头域表示消息发送的时间,时间的描述格式由rfc822定义。例如,Date: Mon,31 Dec 2001 04:25:57GMT

 Web服务器告诉浏览器在2012-11-28 03:30:01这个时间点之前,可以使用缓存文件。发送请求的时间是2012-11-28 03:25:01,即缓存5分钟。

 不过Expires HTTP 1.0的东西,现在默认浏览器均默认使用HTTP 1.1,所以它的作用基本忽略。

 

Cache-control策略(重点关注

 Cache-ControlExpires的作用一致,都是指明当前资源的有效期,控制浏览器是否直接从浏览器缓存取数据还是重新发请求到服务器取数据。只不过Cache-Control选择更多,设置更细致,如果同时设置的话,其优先级高于Expires

http协议头Cache-Control   

值可以是publicprivateno-cacheno- storeno-transformmust-revalidateproxy-revalidatemax-age

各个消息中的指令含义如下:

  1. Public指示响应可被任何缓存区缓存。
  2. Private指示对于单个用户的整个或部分响应消息,不能被共享缓存处理。这允许服务器仅仅描述当用户的部分响应消息,此响应消息对于其他用户的请求无效。
  3. no-cache指示请求或响应消息不能缓存
  4. no-store用于防止重要的信息被无意的发布。在请求消息中发送将使得请求和响应消息都不使用缓存。
  1. max-age指示客户机可以接收生存期不大于指定时间(以秒为单位)的响应。
  1. min-fresh指示客户机可以接收响应时间小于当前时间加上指定时间的响应。
  2. max-stale指示客户机可以接收超出超时期间的响应消息。如果指定max-stale消息的值,那么客户机可以接收超出超时期指定值之内的响应消息。

 下表说明了在不同的情形下,浏览器是将请求重新发送到服务器还是使用缓存的内容。(不同浏览器,不同版本,表现可能会有所差异)

Cache-directive  

打开一个新的浏览器窗口  

在原窗口中单击 Enter 按钮  

刷新  

单击 Back 按钮  

public  

浏览器呈现来自缓存的页面  

浏览器呈现来自缓存的页面  

浏览器重新发送请求到服务器  

浏览器呈现来自缓存的页面  

private  

浏览器重新发送请求到服务器  

第一次,浏览器重新发送请求到服务器;此后,浏览器呈现来自缓存的页面  

浏览器重新发送请求到服务器  

浏览器呈现来自缓存的页面  

no-cache/no-store  

浏览器重新发送请求到服务器  

浏览器重新发送请求到服务器  

浏览器重新发送请求到服务器  

浏览器重新发送请求到服务器  

must-revalidation/proxy-revalidation  

浏览器重新发送请求到服务器  

第一次,浏览器重新发送请求到服务器;此后,浏览器呈现来自缓存的页面  

浏览器重新发送请求到服务器  

浏览器呈现来自缓存的页面  

max-age=xxx (xxx is numeric)  

xxx 秒后,浏览器重新发送请求到服务器  

xxx 秒后,浏览器重新发送请求到服务器  

浏览器重新发送请求到服务器  

xxx 秒后,浏览器重新发送请求到服务器  

 FireFox 31.0版中通过“在原窗口中单击Enter按钮”测试发现,必须要设置publicprivate(其他值未测试),浏览器才会取本地缓存,否则会发出请求,同时需要设置Expires,设置Pragma"Pragma",(如果不设置Expires,设置Pragma无效,仍为no-cache)。

 

还是上面那个请求,web服务器返回的Cache-Control头的值为max-age=300,即5分钟(和上面的Expires时间一致,这个不是必须的)。

  

Last-Modified/If-Modified-Since

 Last-Modified/If-Modified-Since要配合Cache-Control (max-age)使用。

 l  Last-Modified:标示这个响应资源的最后修改时间。web服务器在响应请求时,告诉浏览器资源的最后修改时间。

 l  If-Modified-Since:当资源过期时(使用Cache-Control标识的max-age),发现资源具有Last-Modified声明,则再次向web服务器请求时带上头If-Modified-Since,表示请求时间。web服务器收到请求后发现有头If-Modified-Since 则与被请求资源的最后修改时间进行比对。若最后修改时间较新,说明资源又被改动过,则响应整片资源内容(写在响应消息包体内),HTTP 200;若最后修改时间较旧,说明资源无新修改,则响应HTTP 304 (无需包体,节省浏览),告知浏览器继续使用所保存的cache

 

web服务器(apache, nginx)通常都有校验Last-Modified的功能,而在app服务器中,spring mvc提供了此校验功能,如下示例代码:

 import javax.servlet.http.HttpServletResponse;

 import org.springframework.stereotype.Controller;

 import org.springframework.ui.Model;

 import org.springframework.web.bind.annotation.RequestMapping;

 import org.springframework.web.context.request.WebRequest;

 @Controller

 @RequestMapping("/")

 public class IndexController {

 

     private long lastModified = System.currentTimeMillis();

 

     @RequestMapping("/test")

     public String test(Model model, WebRequest webRequest, HttpServletResponse response) {

         response.setHeader("Cache-Control", "max-age=3600");

         if (webRequest.checkNotModified(lastModified)) {

                // shortcut exit - no further processing necessary

                return null;

          }

          return "index.ftl";

     }

 } 

  

查看checkNotModified方法的spring源码,如果缓存有效,则设置http响应码为304

 public boolean checkNotModified(long lastModifiedTimestamp) {
 if (lastModifiedTimestamp >= 0 && !this.notModified &&
   (this.response == null || !this.response.containsHeader(HEADER_LAST_MODIFIED))) {
  long ifModifiedSince = getRequest().getDateHeader(HEADER_IF_MODIFIED_SINCE);
  this.notModified = (ifModifiedSince >= (lastModifiedTimestamp / 1000 * 1000));
  if (this.response != null) {
   if (this.notModified && METHOD_GET.equals(getRequest().getMethod())) {
    this.response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
   }
   else {
    this.response.setDateHeader(HEADER_LAST_MODIFIED, lastModifiedTimestamp);
   }
  }
 }
 return this.notModified;
}

  

Etag/If-None-Match

Etag/If-None-Match也要配合Cache-Control (max-age)使用。

l  Etagweb服务器响应请求时,告诉浏览器当前资源在服务器的唯一标识(生成规则由服务器觉得)。Apache中,ETag的值,默认是对文件的索引节(INode),大小(Size)和最后修改时间(MTime)进行Hash后得到的

 l  If-None-Match:当资源过期时(使用Cache-Control标识的max-age),发现资源具有Etage声明,则再次向web服务器请求时带上头If-None-MatchEtag的值)web服务器收到请求后发现有头If-None-Match 则与被请求资源的相应校验串进行比对,决定返回200304

  

仅仅设置了Cache-Control : max-age=XXX秒(没有Last-ModifiedEtag的配合)

 这种情况就直接根据max-age设置的时间进行浏览器本地缓存,缓存的key为页面url

 

笔者做了个小测试验证,如下图所示,过了两分钟后,在03:40:38 GMT左右的时候本地缓存失效,即参照的是Date之后的两分钟,并且max-age的优先级高于Expires

 FireFox 31.0版必须要设置 ExpiresPragmamax-age才会起作用,比较诡异)


  

既有Last-Modified何又Etag

 你可能会觉得使用Last-Modified已经足以让浏览器知道本地的缓存副本是否足够新,为什么还需要Etag(实体标识)呢?HTTP1.1Etag的出现主要是为了解决几个Last-Modified比较难解决的问题:

 l  Last-Modified标注的最后修改只能精确到秒级,如果某些文件在1秒钟以内,被修改多次的话,它将不能准确标注文件的修改时间

 l  如果某些文件会被定期生成,当有时内容并没有任何变化,但Last-Modified却改变了,导致文件没法使用缓存

 l  有可能存在服务器没有准确获取文件修改时间,或者与代理服务器时间不一致等情形

 

Etag是服务器自动生成或者由开发者生成的对应资源在服务器端的唯一标识符,能够更加准确的控制缓存。Last-ModifiedETag是可以一起使用的,服务器会优先验证ETag,一致的情况下,才会继续比对Last-Modified,最后才决定是否返回304

  

用户行为与缓存

 浏览器缓存行为还有用户的行为有关!!!

用户操作

Expires/Cache-Control

Last-Modified/Etag

地址栏回车

有效

有效

页面链接跳转

有效

有效

新开窗口

有效

有效

前进、后退

有效

有效

F5刷新

无效

有效

Ctrl+F5刷新

无效

无效

 FireFox中新开窗口,效果如下图:

BFCacheBack Forward Cache)说明直接使用了本地缓存,根本就没有发出请求。

  

总结

浏览器第一次请求:

  

浏览器再次请求时:

 参考:

 http://www.cnblogs.com/skynet/archive/2012/11/28/2792503.html

 http://www.51testing.com/html/43/434343-243768.html

 

  • 大小: 38.6 KB
  • 大小: 24.8 KB
  • 大小: 8.9 KB
  • 大小: 6.5 KB
  • 大小: 22 KB
  • 大小: 45.5 KB
分享到:
评论

相关推荐

    浏览器缓存机制介绍与缓存策略剖析.pptx

    浏览器缓存机制介绍与缓存策略剖析 浏览器缓存机制是指浏览器在请求资源时,对已经请求过的资源进行缓存,以便下次请求时可以直接从缓存中获取,从而提高页面加载速度和减少服务器的压力。本文将详细介绍浏览器缓存...

    浏览器缓存机制 mindMaster脑图与visio流程图

    浏览器缓存机制是互联网浏览体验中的重要组成部分,它极大地提高了网页加载速度,减少了网络带宽的消耗。在本文中,我们将深入探讨浏览器缓存的工作原理,主要包括两种主要类型的缓存:强缓存(Strong Cache)和协商...

    存储篇 1:浏览器缓存机制介绍与缓存策略剖析(1).md

    ### 浏览器缓存机制介绍与缓存策略剖析 浏览器缓存是前端性能优化的一个重要组成部分,其可以减少网络IO消耗,提高访问速度。浏览器缓存的机制可以分为四个方面:MemoryCache、ServiceWorkerCache、HTTPCache和...

    浏览器缓存机制面试常考.zip

    浏览器缓存【2024年浏览器缓存简介】 内容概要: 这篇博客为网络技术初学者提供了一个全面的理解浏览器缓存的知识。通过通俗易懂的语言,本博客介绍了浏览器缓存的工作原理,HTTP缓存控制字段,缓存策略的应用,以及...

    Http页面缓存机制

    浏览器缓存机制可以分为两类:服务器端缓存和浏览器端缓存。服务器端缓存是指服务器端存储的缓存,而浏览器端缓存是指浏览器端存储的缓存。本文主要介绍浏览器端缓存机制。 浏览器端缓存机制的重要性在于它可以减少...

    HTTP+JS+浏览器缓存技术

    浏览器缓存机制可以分为两大类:Expires 策略和 Cache-Control 策略。 一、Expires 策略 Expires 是 Web 服务器响应消息头字段,在响应 http 请求时告诉浏览器在过期时间前浏览器可以直接从浏览器缓存取数据,而...

    js浏览器缓存.doc

    对于使用Prototype.js或其他JavaScript库进行Ajax开发的开发者而言,了解并掌握如何规避浏览器缓存机制至关重要。通过在请求URL中添加随机参数或改变请求方式为POST,可以有效解决因缓存而导致的重复请求失效问题,...

    彻底理解浏览器的缓存机制.docx

    通过对浏览器缓存机制的深入理解,我们可以看到它不仅提升了用户体验,还极大地减轻了服务器的压力。在实际应用中,开发者可以通过合理设置缓存相关的HTTP头字段来优化网站性能,比如使用`Cache-Control`来指定更...

    浏览器HTTP缓存机制

    ### 浏览器HTTP缓存机制详解 #### 一、概述 HTTP缓存机制是现代Web应用中的一个重要组成部分,它能够显著提升用户体验并减轻服务器负载。本文将详细探讨浏览器HTTP缓存的工作原理及其背后的机制。 #### 二、HTTP...

    ..........

    【标题】: "深入理解Chrome浏览器缓存机制与文件结构" 【描述】: "本资料主要探讨了Chrome浏览器的缓存机制,包括HTTP缓存、磁盘缓存以及如何通过文件系统来查看和分析这些缓存。同时,还涵盖了Chrome浏览器的特定...

    2024年浏览器缓存HTTP缓存机制(面试常考).zip

    浏览器缓存【2024年浏览器缓存/HTTP缓存机制(面试常考)简介】 内容概要: 这篇博客为网络技术初学者提供了一个全面的理解浏览器缓存和HTTP缓存机制的指南。通过通俗易懂的语言,本博客介绍了浏览器缓存的工作原理...

    清除浏览器缓存

    在现代互联网应用中,浏览器缓存机制被广泛采用以提升用户体验和减少网络流量消耗。然而,在某些情况下(如开发测试阶段或网站更新后),我们需要清除浏览器缓存来确保用户能够看到最新的网页内容。本文将详细介绍...

    chrome浏览器怎么找缓存视频文件?.docx

    Chrome 浏览器缓存机制 在了解缓存视频文件的查找方法之前,需要了解 Chrome 浏览器的缓存机制。当我们在浏览器中观看视频时,浏览器会将视频文件缓存在本地,以便快速加载视频。缓存的视频文件存储在浏览器的缓存...

    禁止浏览器缓存当前文档内容

    在网页开发中,浏览器缓存机制是为了优化加载速度,但是有时会导致问题,比如服务器端更新的内容无法及时反映到客户端。为了防止这种情况,可以通过设置HTTP响应头来禁止浏览器缓存当前页面。以下是三种常用的响应头...

    面试题浏览器缓存和数据压缩.pdf

    ### 浏览器缓存机制 浏览器缓存机制主要分为两种:强制缓存和协商缓存。 1. **强制缓存**:当浏览器发起请求时,如果强制缓存生效,浏览器将直接从本地缓存中获取数据,不会向服务器发送任何请求。强制缓存可以...

    jsp去除浏览器缓存

    但在某些情况下,我们可能需要禁用缓存机制,例如: - 当页面内容频繁更新时。 - 当我们需要确保用户始终看到最新版本的页面时。 #### 三、JSP中禁用浏览器缓存的方法 在JSP页面中可以通过设置HTTP响应头来实现...

Global site tag (gtag.js) - Google Analytics