前言:

web中有些场景下很多内容是不需要更改的,如果每次请求都向服务器请求那些一段时间内不会变动的内容数据,会造成不必要的带宽浪费。

有时候网络较差时,请求这些内容就需要花费很长时间来打开页面。

因此通过浏览器的缓存机制,协同服务器让浏览器缓存那些不需要频繁变动的资源就可以有效地降低流量消耗和响应时间。

一、什么是http缓存

http缓存指的是:当客户端向服务器请求资源时,会先查看浏览器缓存,如果浏览器有“要请求资源”的副本,就可以直接从浏览器缓存中提取,而不需要从服务器中请求这个资源。

需要注意的是,常见的http缓存只能缓存GET请求的资源,所以下面说的请求缓存皆是指GET请求。

http缓存分类:根据是否需要向服务器发起请求把http缓存分为两个大类,强缓存协商缓存

http缓存都是从第二次请求开始的:

  • 第一次请求资源时,客户端向服务器请求资源,服务器返回响应资源,并在response header中回传资源的缓存参数;
  • 第二次请求资源时,浏览器判断这些请求参数,命中强缓存就返回200,使用磁盘缓存中的资源,不请求服务器,否则就把请求参数加到request header中传给服务器,看是否命中协商缓存,命中则返回304,使用缓存资源,若都没命中则服务器会返回新的资源。

二、强缓存

强缓存是通过设置缓存的到期时间 expires 或者有效时间 max-age ,在有效时间内,缓存不会失效,浏览器直接从浏览器缓存中读取资源。当缓存数据库中没有所请求的资源,或所请求的资源已失效时,才会从服务端请求资源。

与强制缓存相关的请求响应头:

  • Expires

响应头,代表该资源的过期时间。但由于服务端时间和客户端时间可能有误差,这也将导致缓存命中可能有误差,另一方面,Expires是HTTP1.0的产物,故现在大多数使用Cache-Control替代。

  • Cache-Control(优先级高于Expires)

请求/响应头,缓存控制字段,精确控制缓存策略。 Cache-Control有很多属性,不同的属性代表的意义也不同。

  1. private:客户端可以缓存
  2. public:客户端和代理服务器都可以缓存
  3. max-age=x:缓存内容将在x秒后失效
  4. no-cache:不能直接使用缓存,要求向服务器发起请求
  5. no-store:所有内容都不会缓存
  • pragma

pragma 是一个在 HTTP/1.0 中规定的通用首部。设置为no-cache与 Cache-Control: no-cache 效果一致,优先级高于cache-control和expires,即三者同时出现时,先看pragma -> cache-control -> expires。

三、协商缓存

协商缓存需要在服务器端对比资源是否修改,来判断是否可以使用缓存。若未改动,则返回304状态码,浏览器拿到此状态码就可以直接使用缓存数据了。否则服务器返回新资源。

由此可见,在协商缓存中,如何判断资源是否改动就尤为重要啦,现在主要有两种策略:Last-Modified 和 Etag

  • Last-Modified

服务器在响应请求时,会告诉浏览器资源GMT格式的最后修改时间。

浏览器非第一次请求服务器时,请求头会包含 if-Modified-Since 字段,后面跟着在缓存中获得的最后修改时间。服务端收到此请求头发现有if-Modified-Since,则与被请求资源的最后修改时间进行对比,如果一致则返回304和响应报文头,此时浏览器只需要从缓存中获取资源即可。

  • 如果真的被修改:那么开始传输响应一个整体,服务器返回:200 OK
  • 如果没有被修改:那么只需传输响应header,服务器返回:304 Not Modified

Last-Modified 其实用起来不一定完全准确:

  1. Last-Modified标注的最后修改只能精确到秒级,如果某文件在1秒钟以内被修改多次的话,它将不能准确标注文件的修改时间
  2. 如果某些文件被修改了,但是内容并没有任何变化,而Last-Modified却改变了,导致文件没法使用缓存
  3. 有可能存在服务器没有准确获取文件修改时间,或者与代理服务器时间不一致等情形

因此,HTTP1.1推出了Etag,改进了这些问题。

  • Etag(优先级高于Last-Modified)

服务器响应请求时,通过此字段告诉浏览器当前资源在服务器生成的唯一标识(生成规则由服务器决定)。

非第一次请求服务器时,浏览器的请求报文头部(Request Headers)会包含 If-None-Match 字段,后面的值为在缓存中获取的标识。服务器接收到此报文后就用 If-None-Match 的值与被请求资源的唯一标识进行对比。

  • 不同,则说明资源被改动,则返回状态码200,服务器返回新资源。
  • 相同,说明资源未修改,则返回状态码304,浏览器直接从缓存中获取数据资源。

不过etag也存在缺点,就是每次生成表示字符串会增加服务器的开销。所以要如何使用last-modified和etag还需要根据具体需求进行权衡。

四、动动手

好了,理论部分说完了,下面我们自己动手尝试一下

我用nodejs开了一个服务器,用来获取get请求的响应,并在其中设置http缓存的相关属性,网页部分就是一个简单的加载图片,初学nodejs写接口,没有很完善,只是为了弄明白缓存怎么用,仅供参考。

强缓存:

nodejs中get请求部分的代码:

app.get("/api/getPic", (req, res) => {res.setHeader("Cache-Control", "public,max-age=120");  //max-age设置的2分钟let date = new Date(Date.now() + 5000).toUTCString(); //Expires过期时间设置了5分钟后res.setHeader("Expires", date);let data = JSON.stringify({msg: "请求成功",result: [{url:"https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=350525183,1430160676&fm=11&gp=0.jpg"}]});res.send(data);
});

发送一次请求,可以看到强缓存的配置已经设置好了(默认带了协商缓存的etag,但是我也不知道为什么。。。。。。):

之后我立即刷新页面,此时变成酱紫了,status Code是200,后边显示from disk cache,此时的图片资源即从磁盘缓存中获取,不请求服务器:

两分钟后,再次刷新页面,此时status code显示304,即请求的服务器,请求的资源没有被更改,命中的协商缓存:

由于默认带了 Etag协商缓存,所以协商缓存部分就没有手写,感兴趣的小伙伴可自行编写设置 Last-Modified 和 Etag 属性值。

补充:

网络请求的size会出现三种情况

  1. from memory cache (内存缓存)
  2. from disk cache (磁盘缓存)
  3. 资源数值大小

  1. 显示数值的状态码为200, 直接从服务器下载最新资源
  2. from memory cache 不请求网络资源,资源在内存当中,一般js脚本,字体,图片会存放在内存当中
  3. from disk cache 不请求网络资源,在磁盘当中,一般非脚本会存在内存当中,如css

五、不同的网页刷新操作

我们将访问和刷新分为以下三种情况:

  • 标签进入、输入url回车进入:按照指定的缓存策略去操作
  • 按刷新按钮、F5刷新、网页右键“重新加载”:强缓存失效,直接判断协商缓存
  • ctrl+F5强制刷新:所有缓存失效,重新请求服务器数据

http缓存策略之强缓存与协商缓存相关推荐

  1. 200(强缓存)和304(协商缓存)的区别

    本文原链接:https://my.oschina.net/ososchina/blog/494074 https://blog.csdn.net/zl399615007/article/details ...

  2. js 单页面ajax缓存策略,浅谈ajax的缓存机制---IE浏览器方面

    这篇文章主要介绍了IE浏览器关于ajax的缓存机制,文中给大家提到了Ajax解决浏览器的缓存问题,解决方法有很多种.有一定的参考价值,有需要的朋友可以参考一下,希望对你们有所帮助. IE浏览器对于同一 ...

  3. glide默认的缓存图片路径地址_手写一个静态资源中间件,加深了解服务器对文件请求的缓存策略...

    上一篇文章<详解页面静态资源的缓存策略,搞懂强缓存和协商缓存再做性能优化>我们从理论上介绍了浏览器和服务器是如何对静态资源做缓存的,这篇文章我们把它做成一个node服务器的静态资源中间件. ...

  4. html如何获取请求头变量的值。_手写一个静态资源中间件,加深了解服务器对文件请求的缓存策略...

    上一篇文章<详解页面静态资源的缓存策略,搞懂强缓存和协商缓存再做性能优化>我们从理论上介绍了浏览器和服务器是如何对静态资源做缓存的,这篇文章我们把它做成一个node服务器的静态资源中间件. ...

  5. 离线缓存占内存吗_彻底弄懂浏览器缓存策略

    浏览器缓存策略对于前端开发同学来说不陌生,大家都有一定的了解,但如果没有系统的归纳总结,可能三言两语很难说明白,甚至说错,尤其在面试过程中感触颇深,很多候选人对这类基础知识竟然都是一知半解,说出几个概 ...

  6. 前端web:浏览器静态资源缓存策略

    浏览器静态资源缓存策略 浏览器其实提供了两种控制策略,分别是强制缓存和协商缓存 强制缓存 强制缓存:就是强制使用浏览器缓存下来的资源; 在指定的一段时间内用自己缓存的文件就行,不需要再次发出请求. 具 ...

  7. 前端协商缓存强缓存如何使用_http协商缓存与强缓存

    概述 良好的缓存策略可以降低资源的重复加载,提高网页的整体加载速度.通常浏览器的缓存策略分为两种:强缓存和协商缓存. 基本原理浏览器在加载资源的时候,会先根据这个资源的一些http header判断他 ...

  8. 小程序图片缓存策略(不改代码更换OSS图片)

    昨天,后端给我提了一个问题:他更换了CDN上的图片,但是他打开小程序来看,还是旧图片,他尝试过删除小程序,重新进,还是旧图片. 我第一反应是:"你有没有清CDN缓存?" 他说:&q ...

  9. 浏览器HTTP缓存策略

    使用缓存是前端性能优化的重要方式,既可以提高响应的速度又可以减少不必要的重复请求,从而提高服务器的吞吐量.但是有时候缓存并不适用于所有情况,有时候反而会使用户体验变差,因此需要根据不同的请求制定不同的 ...

最新文章

  1. 表达式前后缀表达形式 [zz]
  2. mybatis动态SQL语句
  3. OpenCV--罗德里格斯(Rodrigues)变换
  4. linux 访问centos共享,CentOS访问Windows共享
  5. c 语言 strcmpy的实现
  6. JavaScript-4函数
  7. android 图片查看源码,Android 简单的图片查看器源码
  8. java开源论坛 discuz_Discuz开源论坛
  9. 【转】微服务实战(六):选择微服务部署策略
  10. 保研复习整理——信号与系统
  11. VS2008编译TrueCrypt
  12. 腾讯云轻量服务器和虚拟主机VPS有什么区别?
  13. WMS智能仓储系统——保姆式服务系统
  14. Godot实现项目差异热更新
  15. 用Matlab画散点图
  16. 嵌入式系统概述及特点
  17. java mysql SSM实现的校园门户平台网站系统源码+含开题报告与需求分析+包安装配置
  18. ios 图标的配置
  19. 《炬丰科技-半导体工艺》--技术资料合集十
  20. 关于Vegas制作炫酷文字转场片头效果的教程分享

热门文章

  1. java race condition_java 多线程下race condition问题
  2. 因子分析模型(主成分解)、及与主成分分析模型的联系与区别(附详细案例)
  3. 如何使用EndNote导出参考文献
  4. 数学建模学习笔记(一):插值法
  5. 老板:你们和外包有什么区别?
  6. Meta宣布大裁员,超11000人!毕业前夜员工瑟瑟发抖,坐等明早的大礼包开奖!...
  7. javaweb-jsp(上)
  8. qywechat.class.php,wechat-php-sdk/qywechat.class.php at master · xzw/wechat-php-sdk · GitHub
  9. 中国大学 科研水平 最新排行榜(ESI)
  10. 不装了,我开源了5款人脸生成器!超模脸、网红脸、萌娃脸...