摘要:在Web开发过程中,我们可能会经常遇到浏览器缓存的问题。本文作者详细解释了浏览器缓存的机制,帮助读者更深层次的认识浏览器的缓存。

  流程

  当资源第一次被访问的时候,HTTP头部如下

(Request-Line) GET /a.html HTTP/1.1Host    127.0.0.1User-Agent  Mozilla/5.0 (X11; U; Linux i686; zh-CN; rv:1.9.0.15) Gecko/2009102815 Ubuntu/9.04 (jaunty) Firefox/3.0.15Accept              text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8Accept-Language     zh-cn,zh;q=0.5Accept-Encoding     gzip,deflateAccept-Charset      gb2312,utf-8;q=0.7,;q=0.7Keep-Alive          300Connection          keep-alive

HTTP返回头部如下

(Status-Line)       HTTP/1.1200 OKDate                Thu,26 Nov 200913:50:54 GMTServer              Apache/2.2.11 (Unix) PHP/5.2.9Last-Modified       Thu,26 Nov 200913:50:19 GMTEtag                "8fb8b-14-4794674acdcc0"Accept-Ranges       bytesContent-Length      20Keep-Alive          timeout=5, max=100Connection          Keep-AliveContent-Type        text/html

当资源第一次被访问的时候,http返回200的状态码,并在头部携带上当前资源的一些描述信息,如

Last-Modified      // 指示最后修改的时间Etag                // 指示资源的状态唯一标识Expires             // 指示资源在浏览器缓存中的过期时间

  接着浏览器会将文件缓存到Cache目录下,并同时保存文件的上述信息

  当第二次请求该文件时,浏览器会先检查Cache目录下是否含有该文件,如果有,并且还没到Expires设置的时间,即文件还没有过期,那么此时浏览器将直接从Cache目录中读取文件,而不再发送请求

  如果文件此时已经过期,则浏览器会发送一次HTTP请求到WebServer,并在头部携带上当前文件的如下信息

If-Modified-Since   Thu,26 Nov 200913:50:19 GMTIf-None-Match       "8fb8b-14-4794674acdcc0"

  即把上一次修改的时间,以及上一次请求返回的Etag值(注:即为If-None-Match)一起发送给服务器。服务器在接收到这个请求的时候,先解析Header里头的信息,然后校验该头部信息。

  如果该文件从上次时间到现在都没有过修改或者Etag信息没有变化,则服务端将直接返回一个304的状态,而不再返回文件资源,状态头部如下

(Status-Line)       HTTP/1.1304 Not ModifiedDate                Thu,26 Nov 200914:09:07 GMTServer              Apache/2.2.11 (Unix) PHP/5.2.9Connection          Keep-AliveKeep-Alive          timeout=5, max=100Etag                "8fb8b-14-4794674acdcc0"

  这样,就能够很大程度上减少网络带宽以及提升用户的浏览器体验。

  当然,如果服务器经过匹配发现文件修改过了,就会将文件资源返回,并带上新文件状态信息。

  基本字段

  Pragma

  Pragma头域用来包含实现特定的指令,最常用的是Pragma:no-cache。在HTTP/1.1协议中,它的含义和Cache- Control:no-cache相同。

  Expires

  文件在本地缓存的过期时间,如果浏览器发现缓存中的文件没有过期,则不发送请求(有例外,后面介绍)

  Cache-Control

  Cache -Control指定请求和响应遵循的缓存机制。 //   怎么理解?

  在请求消息或响应消息中设置 Cache-Control并不会修改另一个消息处理过程中的缓存处理过程。请求时的缓存指令包括

no-cache、no-store、max-age、 max-stale、min-fresh、only-if-cached

响应消息中的指令包括

public、private、no-cache、no- store、no-transform、must-revalidate、proxy-revalidate、max-age

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

  1. Public指示响应可被任何缓存区缓存。

  2. Private指示对于单个用户的整个或部分响应消息,不能被共享缓存处理。这允许服务器仅仅描述当用户的部分响应消息,此响应消息对于其他用户的请求无效。

  3. no-cache指示请求或响应消息不能缓存

  4. no-store用于防止重要的信息被无意的发布。在请求消息中发送将使得请求和响应消息都不使用缓存。

  5. max-age指示客户机可以接收生存期不大于指定时间(以秒为单位)的响应。

  6. min-fresh指示客户机可以接收响应时间小于当前时间加上指定时间的响应。

  7. max-stale指示客户机可以接收超出超时期间的响应消息。如果指定max-stale消息的值,那么客户机可以接收超出超时期指定值之内的响应消息。

  Etag/If-None-Match

  一对验证文件实体的标记“Entity Tag”的响应/请求头Apache中,ETag的值,默认是对文件的索引节(INode),大小(Size)和最后修改时间(MTime)进行Hash后得到的

  Last-Modified/If-Modified-Since

  一对验证文件的修改时间的响应/请求头

  Expires、Cache-Control、Last-Modified、ETag是RFC 2616(HTTP/1.1)协议中和网页缓存相关的几个字段。

  前两个用来控制缓存的失效日期,浏览器可通过它来判定,需不需要发出HTTP请求;

  后两个用来验证网页的有效性,服务器端利用它来验证这个文件是否需要重新返回

  Last-Modified VS Etag

  既然有了Last-Modified,为什么还要用ETag字段呢?因为如果在一秒钟之内对一个文件进行两次更改,Last-Modified就会不正确。因此,HTTP/1.1利用Entity Tag头提供了更加严格的验证。

  不同的情况

  上面描述的是一个普通的浏览器缓存状态,在实际应用中,如页面跳转(点击页面链接跳转,window.open,在地址栏敲回车,刷新页面)等操作,会有一些区别

  普通页面跳转

  普通页面跳转包括链接点击跳转,用js脚本打开新页面(window.open)

  无缓存情况下,请求会返回所有资源结果

  设置Expires并且未过期时,浏览器将不会发出http请求

  如果Expires过期,则会发送相应请求,并附带上Last-Modifed等信息,供服务器校验

  页面刷新(F5)

  这种情况一下,一般会看到很多304的请求,就是说即便资源设置了Expires且未过期,浏览器也会发送相应请求

  IE和FF稍有区别

  IE:

If-Modified-Since   Wed,18 Nov 200915:54:52 GMTIf-None-Match   "2360492659"Pragma: no-cache    // 禁止缓存

  FF:

If-Modified-Since   Wed,18 Nov 200915:54:52 GMTIf-None-Match   "2360492659"Cache-Control   max-age=0   // 文件立即过期

  强制刷新(Ctrl+F5)

  效果和无缓存时候一致,返回200的结果

  一些特殊的资源

  IFRAME

  FLASH

  异步获取的数据

  待研究……

转自:http://kb.cnblogs.com/page/73901/

--------------------------------------------------------Cache Control HTTP 1.1中用----------------------------------------------------------------------

http://blog.csdn.net/youngerchen/article/details/6116147

HTTP协议分别在 1.0 / 1.1 两个时代推出了 Expires / Cache-control 两种cache策略,这里我们无需了解全部的细节,无需记住整个RFC内容,但是当我们需要使用HTTP cache策略时,我们需要注意以下细节:
Expires 是HTTP 1.0 那个时代的东西了,目前来看,可以不使用了,因为HTTP 1.0 的user agent占有率在 0.1% 以下(我们主要面向的web浏览器均默认使用HTTP 1.1),Cache-control 是 HTTP 1.1 的新特性,也是我们主要做文章使用cache策略的工具.

Cache策略:
#1 保鲜期only 
这个是最最基础的一种策略,只需要在响应头中设定:
Cache-control: max-age=[secs]
[secs]是cache在客户端存活的秒数,例如 Cache-control: max-age=1800 表明cache的时间是半小时,只使用这样一个声明就可以使浏览器能够将这个HTTP响应的内容写入临时目录做cache.

PS:http://www.itlearner.com/article/4877

因为Expires头使用一个特定的时间,它要求服务端和客户端的时钟严格同步;另外,过期日期需要经常检查,一旦过期日期到了,需要在服务器中配置提供一个新的日期。所以,HTTP1.1引入了Cache-Control头来克服Exipres头的限制。Cache-Control使用max-age指令指定组件被缓存多久,它以秒为单位定义了一个更新窗。使用带有max-age的Cache-Control可以消除Expires的限制,但对于不支持HTTP1.1的应用,仍希望使用Expires头。可以同时制定这两个响应头,如果两者同时出现时,HTTP规范规定max-age指令将重写Expires头。

HTTP请求中浏览器的缓存机制(转)的更多相关文章

  1. HTTP请求中浏览器的缓存机制

    摘要:在Web开发过程中,我们可能会经常遇到浏览器缓存的问题.本文作者详细解释了浏览器缓存的机制,帮助读者更深层次的认识浏览器的缓存. 流程 当资源第一次被访问的时候,HTTP头部如下 (Reques ...

  2. HTTP请求中浏览器缓存

    本文导读:浏览器缓存机制,其实主要就是HTTP协议定义的缓存机制.客户端缓存是否需要是可以在服务端代码上控制的.那就是响应头.响应头告诉缓存器不要保留缓存,缓存器就不会缓存相应内容:如果请求信息是需要 ...

  3. 彻底理解浏览器的缓存机制(http缓存机制)

    一.概述 浏览器的缓存机制也就是我们说的HTTP缓存机制,其机制是根据HTTP报文的缓存标识进行的,所以在分析浏览器缓存机制之前,我们先使用图文简单介绍一下HTTP报文,HTTP报文分为两种: 同步s ...

  4. 内置组件 && vue中强大的缓存机制之keep-alive

    vue中强大的缓存机制之keep-alive 最近在用vue做项目,在切换页面时发现切换回原来的页面无法保存原来的状态. 如A页面需要ajax请求数据,然后切换到B页面做某些事情,再切换回A页面时,A ...

  5. python中变量的缓存机制

    同一文件中, 变量的缓存机制 (在此范围内的相同值内存地址一样) Number: int:                -5 ~ 正无穷 float:             非负数 bool:  ...

  6. Web浏览器的缓存机制

    Web缓存的工作原理 所有的缓存都是基于一套规则来帮助他们决定什么时候使用缓存中的副本提供服务(假设有副本可用的情况下,未被销毁回收或者未被删除修改).这些规则有的在协议中有定义(如HTTP协议1.0 ...

  7. 【Web缓存机制系列】2 – Web浏览器的缓存机制

    Web缓存的工作原理 所有的缓存都是基于一套规则来帮助他们决定什么时候使用缓存中的副本提供服务(假设有副本可用的情况下,未被销毁回收或者未被删除修改).这些规则有的在协议中有定义(如HTTP协议1.0 ...

  8. 【Web缓存机制系列】2 – Web浏览器的缓存机制-(新鲜度 校验值)

    Web缓存的工作原理 所有的缓存都是基于一套规则来帮助他们决定什么时候使用缓存中的副本提供服务(假设有副本可用的情况下,未被销毁回收或者未被删除修改).这些规则有的在协议中有定义(如HTTP协议1.0 ...

  9. 从php到浏览器的缓存机制,不得不看!

    所有的php程序员都知道在php脚本里面执行 echo "1";访客的浏览器里面就会显示"1". 但是我们执行下面的代码的时候,并不是显示"1&quo ...

  10. PHP到浏览器的缓存机制

    参考地址:http://www.cnblogs.com/godok/p/6341300.html 所有的php程序员都知道在php脚本里面执行 echo “1”;访客的浏览器里面就会显示“1”. 但是 ...

随机推荐

  1. 2021-7-12 VUE的组件认识

    VUE组件简单实例 <!DOCTYPE html> <html> <head> <title> </title> </head> ...

  2. centos7.9 时间相关整理

    1.date / timedatectl 显示当前时间(秒): date / date +"%Y-%m-%d %H:%M:%S" (%Y等含义通过data --h查看) 显示当前时 ...

  3. 浏览器工作原理及V8引擎

    浏览器解析过程 当浏览器加载html资源时,会进行如下的解析过程 遇见 HTML 标记,构建 DOM 树 遇见 style/link 标记调用相应解析器处理CSS标记,并构建出CSS样式树 遇见 sc ...

  4. [nginx]lua控制响应头

    前言 适用场景:添加CDN缓存时间.操作set-cookie.标记业务数据类型等. 获取响应头 指令:ngx.resp.get_headers 语法:headers = ngx.resp.get_he ...

  5. linux编译安装nginx

    前言 系统:centos7和debian11均验证可行 本文将nginx默认支持的编译参数都加上了,所以需要的依赖比较多,酌情配置. 步骤 假设安装在/usr/local/nginx,创建安装目录 m ...

  6. 自定义组件使用v-model

    场景描述 我们在一个系统中,会出现这样的情况, 有一个联系人的下拉框,这个下拉框中的数据是从服务端获取的. 在很多页面都需要使用这个联系人(下拉框). 我们通常是这样做的: 写一个下拉框组件然后调用接 ...

  7. Kioptrix Level 1

    Kioptrix这个系列靶机默认是桥接模式,如果我们kali使用NAT是扫描不到靶机的,通过VM的靶机网络设置也不能更改成功. 解决方式:每次下载好靶机先不导入VM,如果已经导入,需要"移除 ...

  8. pytest-xdist分布式测试原理浅析

    pytest-xdist执行流程: 解析命令行参数:pytest-xdist 会解析命令行参数,获取用户指定的分发模式.进程数.主机列表等信息. 加载测试用例:pytest-xdist 会加载所有的 ...

  9. 在.NET Framework中使用RocketMQ(阿里云版)实战【第二章】

    章节 第一章:https://www.cnblogs.com/kimiliucn/p/17662052.html 第二章:https://www.cnblogs.com/kimiliucn/p/176 ...

  10. 细数2019-2023年CWE TOP 25 数据,看软件缺陷的防护

    本文分享自华为云社区<从过去5年CWE TOP 25的数据看软件缺陷的防护>,作者:Uncle_Tom. "以史为鉴,可以知兴替".CWE 已经连续5年发布了 CWE ...