http請求瀏覽器的緩存機制

轉載自:http://kb.cnblogs.com/page/73901/

流程

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

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

HTTP返回头部如下

(Status-Line) HTTP/1.1 200 OK
Date Thu, 26 Nov 2009 13:50:54 GMT
Server Apache/2.2.11 (Unix) PHP/5.2.9
Last-Modified Thu, 26 Nov 2009 13:50:19 GMT
Etag "8fb8b-14-4794674acdcc0"
Accept-Ranges bytes
Content-Length 20
Keep-Alive timeout=5, max=100
Connection Keep-Alive
Content-Type text/html

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

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

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

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

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

If-Modified-Since Thu, 26 Nov 2009 13:50:19 GMT
If-None-Match "8fb8b-14-4794674acdcc0"

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

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

(Status-Line) HTTP/1.1 304 Not Modified
Date Thu, 26 Nov 2009 14:09:07 GMT
Server Apache/2.2.11 (Unix) PHP/5.2.9
Connection Keep-Alive
Keep-Alive timeout=5, max=100
Etag "8fb8b-14-4794674acdcc0"

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

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

  基本字段

  Pragma

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

  Expires

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

  Cache-Control

  Cache -Control指定请求和响应遵循的缓存机制。

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

  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且未过期,浏览器也会发送相应请求

时间: 2024-08-10 04:48:37

http請求瀏覽器的緩存機制的相关文章

獲得瀏覽器顯示標簽的真實的長寬高

var rect = $('.CalendarColumn').get(0).getBoundingClientRect(); $('.CalendarColumn').get(0).getBoundingClientRect()ClientRect {height: 73, width: 191, left: 45, bottom: 212, right: 236…} bottom: 212 height: 73 left: 45 right: 236 top: 139 width: 191

jquery easyui 1.3.4 datagrid pageNumber 設置導致兩次請求的解决方案

$('#table').datagrid({ url: '/get/data/path/to/your/server', pageNumber: 2, pageSize: 10, ... }); 當手動設置 pageNumber >= 2 時,查看網络請求會有兩次,並且第二次的請求的 pageNumber == 1: 二.原因: jquery.easyui.min.js 1.3.4 的 7821-7828 行代碼: 因为分頁控件初始化参數 total == 0, pageNumber == 1,

用編程方式證明Hibernate中一級緩存的存在

寫一個查詢小例子 // 测试一级缓存的存在 @Test public void demo8(){ Session session = HibernateUtils.openSession(); Transaction transaction = session.beginTransaction(); Book book = (Book) session.get(Book.class, "2c2882bc42f1e93b0142f1e93d2c0000"); System.out.pri

請求轉發和重定向

相同点--->页面都会实现跳转不同点--->请求转发的时候,url不会产生变化      307 重定向的时候,url地址栏会发生变化   302 请求转发只能在当前应用中跳转 重定向不仅可以完成服务器同一个项目间进行跳转,还可以在不同项目间进行跳转 原文地址:https://www.cnblogs.com/rzkwz/p/12392995.html

POJ-2195 Going Home---KM算法求最小权值匹配(存负边)

题目链接: https://vjudge.net/problem/POJ-2195 题目大意: 给定一个N*M的地图,地图上有若干个man和house,且man与house的数量一致.man每移动一格需花费$1(即单位费用=单位距离),一间house只能入住一个man.现在要求所有的man都入住house,求最小费用. 思路: KM算法传送门: 理解篇    运用篇 每个man和house建立带权二分图,曼哈顿距离就是边的值,这里要求最小费用,也就是二分图最小权值匹配,但是KM算法求的是二分图最

Redis学习笔记~Redis实现多个緩存服务器,读写分离

回到目录 Redis这个Nosql的存储系统一般会被部署到linux系统中,我们可以把它当成是一个数据服务器,对于并发理大时,我们会使用多台服务器充当Redis服务器,这时,各个Redis之间也是分布式的,而Redis与WWW之间也是一种分布式,对于各个redis之间的分布式不需要我们去干预,它是由我们的redis客户端去负责链接的,你当时链到哪台服务器,完全由客户端去控制. 下面看一下redisConfig里的相关配置,我加了一些说明 /// <summary> /// redis主要信息的

如何在 iOS App 中整合 Facebook 廣告

原文:Displaying Facebook Ads in Your iOS Apps 作者:GABRIEL THEODOROPOULOS 译者:kmyhy 不久前有人問我如何在項目中集成 Facebook 的廣告.因為之前沒用過,以為一定很難,所以事先查閱了大量文檔.在通讀完文檔之後,發現其實並不是很難,僅僅幾分鐘我就能夠搞定我的第一個 Facebook 廣告 App! Facebook 廣告是一種將廣告集成到你的 app 中的方法,使你可以通過廣告的點擊量來獲得收入.這個方法(集成廣告)并不

Asp.net attributes collection

<?xml version="1.0" encoding="utf-8"?><root>  <ContralNames>    <Contral Name="@Page">      <Attribute Name="Buffer">是否啟用http響應緩沖</Attribute>      <Attribute Name="ClassNa

JS中setTimeout()的使用方法具体解释

1. SetTimeOut()              1.1 SetTimeOut()语法样例              1.2 用SetTimeOut()运行Function              1.3 SetTimeOut()语法样例              1.4 设定条件使SetTimeOut()停止              1.5 计分及秒的counter    2. ClearTimeout()    3.  Set Flag   10.1 setTimeout( )