http协商缓存VS强缓存

之前一直对浏览器缓存只能描述一个大概,深层次的原理不能描述上来;终于在前端的两次面试过程中被问倒下,为了泄恨,查阅一些资料最终对其有了一个更深入的理解,废话不多说,赶紧来看看浏览器缓存的那些事吧,有不对的地方,请各位不吝赐教啊。

本文主要讲解浏览器端的缓存,缓存的作用是不言而喻的,能够极大的改善网页性能,提高用户体验。

1、浏览器缓存

缓存这东西,第一次必须获取到资源后,然后根据返回的信息来告诉如何缓存资源,可能采用的是强缓存,也可能告诉客户端浏览器是协商缓存,这都需要根据响应的header内容来决定的。下面用两幅图来描述浏览器的缓存是怎么玩的,让大家有个大概的认知。

浏览器第一次请求时:

浏览器后续在进行请求时:

从上图可以知道,浏览器缓存包含两种类型,即强缓存(也叫本地缓存)和协商缓存,浏览器在第一次请求发生后,再次请求时:

  • 浏览器在请求某一资源时,会先获取该资源缓存的header信息,判断是否命中强缓存(cache-control和expires信息),若命中直接从缓存中获取资源信息,包括缓存header信息;本次请求根本就不会与服务器进行通信;在firebug下可以查看某个具有强缓存资源返回的信息,例如本地firebug查看的一个强缓存js文件

  • 如果没有命中强缓存,浏览器会发送请求到服务器,请求会携带第一次请求返回的有关缓存的header字段信息(Last-Modified/If-Modified-Since和Etag/If-None-Match),由服务器根据请求中的相关header信息来比对结果是否协商缓存命中;若命中,则服务器返回新的响应header信息更新缓存中的对应header信息,但是并不返回资源内容,它会告知浏览器可以直接从缓存获取;否则返回最新的资源内容

强缓存与协商缓存的区别,可以用下表来进行描述:

  获取资源形式 状态码 发送请求到服务器
强缓存  从缓存取  200(from cache) 否,直接从缓存取
协商缓存  从缓存取  304(not modified) 是,正如其名,通过服务器来告知缓存是否可用

2、强缓存相关的header字段

强缓存上面已经介绍了,直接从缓存中获取资源而不经过服务器;与强缓存相关的header字段有两个:

  1. expires,这是http1.0时的规范;它的值为一个绝对时间的GMT格式的时间字符串,如Mon, 10 Jun 2015 21:31:12 GMT,如果发送请求的时间在expires之前,那么本地缓存始终有效,否则就会发送请求到服务器来获取资源
  2. cache-control:max-age=number,这是http1.1时出现的header信息,主要是利用该字段的max-age值来进行判断,它是一个相对值;资源第一次的请求时间和Cache-Control设定的有效期,计算出一个资源过期时间,再拿这个过期时间跟当前的请求时间比较,如果请求时间在过期时间之前,就能命中缓存,否则就不行;cache-control除了该字段外,还有下面几个比较常用的设置值:
    • no-cache:不使用本地缓存。需要使用缓存协商,先与服务器确认返回的响应是否被更改,如果之前的响应中存在ETag,那么请求的时候会与服务端验证,如果资源未被更改,则可以避免重新下载。
    • no-store:直接禁止游览器缓存数据,每次用户请求该资源,都会向服务器发送一个请求,每次都会下载完整的资源。
    • public:可以被所有的用户缓存,包括终端用户和CDN等中间代理服务器。
    • private:只能被终端用户的浏览器缓存,不允许CDN等中继缓存服务器对其缓存。

  注意:如果cache-control与expires同时存在的话,cache-control的优先级高于expires

3、协商缓存相关的header字段

协商缓存都是由服务器来确定缓存资源是否可用的,所以客户端与服务器端要通过某种标识来进行通信,从而让服务器判断请求资源是否可以缓存访问,这主要涉及到下面两组header字段,这两组搭档都是成对出现的,即第一次请求的响应头带上某个字段(Last-Modified或者Etag),则后续请求则会带上对应的请求字段(If-Modified-Since或者If-None-Match),若响应头没有Last-Modified或者Etag字段,则请求头也不会有对应的字段

  1. Last-Modified/If-Modified-Since
    二者的值都是GMT格式的时间字符串,具体过程:

      • 浏览器第一次跟服务器请求一个资源,服务器在返回这个资源的同时,在respone的header加上Last-Modified的header,这个header表示这个资源在服务器上的最后修改时间
      • 浏览器再次跟服务器请求这个资源时,在request的header上加上If-Modified-Since的header,这个header的值就是上一次请求时返回的Last-Modified的值
      • 服务器再次收到资源请求时,根据浏览器传过来If-Modified-Since和资源在服务器上的最后修改时间判断资源是否有变化,如果没有变化则返回304 Not Modified,但是不会返回资源内容;如果有变化,就正常返回资源内容。当服务器返回304 Not Modified的响应时,response header中不会再添加Last-Modified的header,因为既然资源没有变化,那么Last-Modified也就不会改变,这是服务器返回304时的response header
      • 浏览器收到304的响应后,就会从缓存中加载资源
      • 如果协商缓存没有命中,浏览器直接从服务器加载资源时,Last-Modified的Header在重新加载的时候会被更新,下次请求时,If-Modified-Since会启用上次返回的Last-Modified值
  2. Etag/If-None-Match
    这两个值是由服务器生成的每个资源的唯一标识字符串,只要资源有变化就这个值就会改变;其判断过程与Last-Modified/If-Modified-Since类似,与Last-Modified不一样的是,当服务器返回304 Not Modified的响应时,由于ETag重新生成过,response header中还会把这个ETag返回,即使这个ETag跟之前的没有变化。

 4、既生Last-Modified何生Etag

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

  • 一些文件也许会周期性的更改,但是他的内容并不改变(仅仅改变的修改时间),这个时候我们并不希望客户端认为这个文件被修改了,而重新GET;
  • 某些文件修改非常频繁,比如在秒以下的时间内进行修改,(比方说1s内修改了N次),If-Modified-Since能检查到的粒度是s级的,这种修改无法判断(或者说UNIX记录MTIME只能精确到秒);
  • 某些服务器不能精确的得到文件的最后修改时间。

这时,利用Etag能够更加准确的控制缓存,因为Etag是服务器自动生成或者由开发者生成的对应资源在服务器端的唯一标识符。

Last-Modified与ETag是可以一起使用的,服务器会优先验证ETag,一致的情况下,才会继续比对Last-Modified,最后才决定是否返回304

5、用户的行为对缓存的影响

盗用网上的一张图,基本能描述用户行为对缓存的影响

时间: 2024-10-12 21:30:27

http协商缓存VS强缓存的相关文章

说说web缓存-强缓存、协商缓存

网上关于WEB缓存的文章很多,今天汇总一下. 为什么要用缓存 一般针对静态资源如CSS,JS,图片等使用缓存,原因如下: 请求更快:通过将内容缓存在本地浏览器或距离最近的缓存服务器(如CDN),在不影响网站交互的前提下可以大大加快网站加载速度. 节省带宽:对于已缓存的文件,可以减少请求带宽甚至无需请求网络. 降低服务器压力:在大量用户并发请求的情况下,服务器的性能受到限制,此时将一些静态资源放置在网络的多个节点,可以起到均衡负载的作用,降低服务器的压力. 缓存分类 缓存分为服务端侧(server

host缓存,浏览器缓存---解决host缓存带来的伤

1.缓存 缓存,对应工程师来讲简直太熟悉了,太方便了,省略到资源或数据的获取方式,直接缓存到离用户访问最快的地方,也降低服务器的压力,比如: (1)静态文件获取 服务器->cdn->本地磁盘->本地内存 (2)数据获取 数据库->内存型数据库 (3)host 缓存 主域名服务器->顶级域名服务器->根域名服务器->网络服务提供商缓存->路由器缓存->系统缓存->浏览器缓存 缓存的好处不言而喻,提升用户的访问速度,降低服务端的压力,问题就是:多份数

nginx 配置 HTTP 强缓存

server { listen 80; server_name tirion.me www.tirion.me; # note that these lines are originally from the "location /" block root /home/www/wordpress; index index.php index.html index.htm; location / { try_files $uri $uri/ =404; } error_page 404

《逐梦旅程 WINDOWS游戏编程之从零开始》笔记6——Direct3D中的顶点缓存和索引缓存

第12章 Direct3D绘制基础 1. 顶点缓存 计算机所描绘的3D图形是通过多边形网格来构成的,网网格勾勒出轮廓,然后在网格轮廓的表面上贴上相应的图片,这样就构成了一个3D模型.三角形网格是构建物体模型的基本单元,而一个三角形有3个顶点,为了能够使用大量三角形组成三角形网格来描述物体,需要首先定义号三角形的顶点(Vertex),3个顶点确定一个三角形,顶点除了定义每个顶点的坐标位置外,还还含有颜色等其他属性. 在Direct3D中,顶点的具体表现形式是顶点缓存,顶点缓存保存了顶点数据的内存空

【缓存】系统缓存全解析 (上)

有时候总听到网友说网站运行好慢,不知如何是好:有时候也总见到一些朋友写的网站功能看起来非常好,但访问性能却极其的差.没有"勤俭节约"的意识,势必会造成"铺张浪费".如何应对这种情况,充分利用系统缓存则是首要之道. 系统缓存有什么好处呢?举个简单的例子,你想通过网页查询某些数据,而这些数据并非实时变化,或者变化的时间是有期限的.例如查询一些历史数据.那么每个用户每次查的数据都是一样的.如果不设置缓存,ASP.NET也会根据每个用户的请求重复查询n次,这就增加了不必要的

本地应用缓存算法和缓存策略的介绍

特别声明:该文章是 本人在网上搜索到的一些资料,稍作整理而成的,还望大家不要误会,具体出自于那本人也已经忘记.还请大家不要误会!!!   通过设计良好的数据分块.预取.替换.更新等算法来提高对缓存内容的命中率和一致性. 1)数据分块      Memcached默认情况下采用了名为Slab Allocator的机制分配.管理内存.在该机制出现以前,内存的分配是通过对所有记录简单地进行malloc和free来进行的.但是,这种方式会导致内存碎片,加重操作系统内存管理器的负担,最坏的情况下,会导致操

[转]缓存、缓存算法和缓存框架简介

以下内容转自:http://www.leexiang.com/cache-algorithm (转载请注明出处)-----------------------------------分割线---------------------------------------------- 引言 我们都听过 cache,当你问他们是什么是缓存的时候,他们会给你一个完美的答案,可是他们不知道缓存是怎么构建的,或者没有告诉你应该采用什么标准去选择缓存框架.在这边文章,我们会去讨论缓存,缓存算法,缓存框架以及哪

Android缓存机制&一个缓存框架推荐

1.先推荐一个轻量级缓存框架--ACache(ASimpleCache) ACache介绍: ACache类似于SharedPreferences,但是比SharedPreferences功能更加强大,SharedPreferences只能保存一些基本数据类型.Serializable.Bundle等数据, 而Acache可以缓存如下数据: 普通的字符串.JsonObject.JsonArray.Bitmap.Drawable.序列化的java对象,和 byte数据. 主要特色: 1:轻,轻到只

缓存、缓存算法和缓存框架

译者:lixiang 译文:http://www.zavakid.com/25 原文:http://www.jtraining.com/component/content/article/35-jtraining-blog/98.html 引言 我们都听过 cache,当你问他们是什么是缓存的时候,他们会给你一个完美的答案,可是他们不知道缓存是怎么构建的,或者没有告诉你应该采用什么标准去选择缓存框架.在这边文章,我们会去讨论缓存,缓存算法,缓存框架以及哪个缓存框架会更好. 面试 “缓存就是存贮数