很久没有写博客了,趁现在也快过年,最近项目不是很忙,写一篇博客做为2018年的开始,重拾刚毕业的几年前写博客的冲动。http协议是每个程序猿应该需要知道的东西,不管是前端人员还是后端人员,以前在上家公司的时候,因为项目的需要,曾经专门去了解过cdn,其中就需要掌握http协议中的缓存相关知识。

http缓存流程图

直接上图,后文会具体的叙述

http协议

在介绍http缓存之前,作为知识铺垫,先简单介绍下http报文。http报文就是客户端(如浏览器)和web服务器通信时发送和响应的的数据。

http请求由三部分组成分别是请求行、消息报头、请求正文

http 响应也是由三个部分组成,分别是:状态行、消息报头、响应正文

与缓存相关的信息,都包含在消息报头(header)中。不了解http协议的,先补充下http协议的知识,google搜索一大堆,本文就直接略过了。

http响应头中相关缓存字段

随便请求一个网页,这里我们打开百度首页,打开浏览器的调试工具

Expires

Expires的值为web服务器返回的到期时间(GMT 格林威治时间),浏览器下次请求时间小于服务器返回的时间则浏览器直接从缓存中获取数据,而不用再次发送请求。

Cache-Control

Cache-Control常见的取值有private、public、no-cache、max-age,no-store

private:客户端可以缓存

public :客户端和代理服务器都可缓存

max-age=<seconds>:缓存存储的最大周期,超过这个时间缓存被认为过期(单位秒)

no-cache:这个很容易让人产生误解,使人误以为是响应不被缓存,实际上Cache-Control:no-cache是会被缓存的,

                 只不过每次在向浏览器提供响应数据时,浏览器每次都要向服务器发送请求,由服务器来决策来评估缓存的有效性

no-store: 所有内容都不缓存(真真的不缓存)

更多详细的Cache-Control的取值参考MDN文档https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Cache-Control

强制缓存:Expires和Cache-Control区别

Expires和Cache-control称为强制缓存,都是在缓存未失效时,浏览器不向服务端发起请求,直接从缓存中取数据。也许你会有疑问,都是一样的作用,为什么要两个都存在呢?

Expires是上古时代Http1.0的东西了,现在默认浏览器均默认使用的是Http1.1了,所以它的作用是可以基本忽略。Expires有一个缺点,就是返回的时间的服务器的绝对时间,用本地时间和服务端时间比较是否过期,是不严谨的,用户是可以随便修改本地时间的,那这样缓存随时可以过期,所以被Cache-Control:max-age=<seconds>取代了,在http1.1中Cache-Control优先级高于Expires。软件工程的特点是向下兼容,Expires一直就没有抛弃,对于使用http1.0协议的浏览器仍然有作用。

Last-Modified

服务器响应浏览器请求,告诉浏览器资源的最后修改时间

Etag

服务器响应请求时,告诉客户端(浏览器)当前请求的资源在服务器标识(Etag的生成算法由服务器决定,不同的web服务器生成etag的算法可能还不一样,Http协议并没有要求etag的生成规则,如文件小的时候可以使用md5sum sha1sum,或者根据文件修改时间,文件大小,文件inode文件属性综合生成,这里不做详细叙述),我们可以将其理解为一个资源的唯一标识,只要文件发生变化Etag的值也变化。

对比缓存:Last-Modified/If-Modified-Since和Etag/If-None-Match

Last-Modified和Etag称为对比缓存,所谓对比缓存,顾明思议,就是需要服务器来比较判断,来告诉客户端(浏览器)是否可以使用本地缓存,对比缓存生效时,服务器返回给客户端(浏览器)的Http Code为304,服务器只是返回的http header信息,并无响应正文,客户端通过服务器返回的状态码304,知道本地缓存并无修改,可以直接使用本地缓存,这样大大的较少的客户端请求响应时间。

对比缓存大致流程是这样的,当浏览器请求服务器的某资源时, 服务器得到资源的最后修改时间(Last-Modified)或根据一定的算法生成资源的标识(Etag),并将Last-Modified或If-Modified-Since返回给浏览器,浏览器把Last-Modified或Etag 和 资源内容同时缓存在本地,当下次再次向服务器请求此资源时,会将If-Modified-Since: Mon, 07 Nov 2016 07:51:11 GMT 或If-None-Match: xxxxxxx"的请求头把发送给服务器,服务器再次计算资源的Last-Modified或Etag,如果和客户端传来的值比较不相同,则表明资源发生了变化,则给浏览器返回Http Code 200。并将资源内容返回给浏览器,如果相同表示没有变化就给浏览器返回Http Code 304 ,并不需要返回资源内容给浏览器。

对于浏览器来说的话,一般会在强制缓存过期的情况下(或者按F5刷新,不同的浏览器可能不一样,firefox是按F5)如果资源原先的响应header中带有Last-Modified和Etag的话,浏览器请求时会在请求header中带上If-Modified-Since和If-None-Match。

Last-Modified和Etag区别

在这里,也许你可能会问,通过Last-Modified就可以知道资源内容是否发生了变化,为什么还需要Etag呢,这不是多此一举吗?,主要原因Etag解决了Last-modified没能解决的问题,Etag比Last-Modified更加严谨。

1.一些文件也许会周期性的更改,但是他的内容并不改变(仅仅改变的修改时间),这个时候我们并不希望客户端认为这个文件被修改了
      2.某些文件修改非常频繁,比如在秒以下的时间内进行修改,(比方说1s内修改了N次),If-Modified-Since能检查到的粒度是s级的,这种修改无法判断

3.如需要对动态生成的内容做缓存,那就可以用etag来控制缓存了

需要注意的是,如果同时有Last-Modified和Etag存在,在发送请求时,浏览器会一次性的将这两个值都发给服务器,没有优先级,服务器是都比较,还是只比较一个,不同的web服务器可能比较逻辑不一样吧。具体的不深究了。

Http请求头中Cache-Control: no-cache的意义

一般按ctrl+f5强制刷新时,请求头里面都带有Cache-Control: no-cache,其实这是跳过本地的强制缓存和告诉服务器跳过对比缓存,也就是重新请求资源了。对于前端同学在通过GET请求后端API接口时,在ajax的请求头中统一带上Cache-Control: no-cache。

总结

1. 对于强制缓存,服务器通知浏览器一个缓存时间,在缓存时间内,下次请求,直接用缓存,不在时间内,执行对比缓存策略。

2. 对于对比缓存,将缓存信息中的Etag和Last-Modified通过请求发送给服务器,由服务器校验,返回304状态码时,浏览器直接使用缓存。

http缓存知多少的更多相关文章

  1. 知乎技术分享:从单机到2000万QPS并发的Redis高性能缓存实践之路

    本文来自知乎官方技术团队的“知乎技术专栏”,感谢原作者陈鹏的无私分享. 1.引言 知乎存储平台团队基于开源Redis 组件打造的知乎 Redis 平台,经过不断的研发迭代,目前已经形成了一整套完整自动 ...

  2. 智能dns或CDN应用中,如何很好的解决DNS缓存问题? - 知乎

    智能dns或CDN应用中,如何很好的解决DNS缓存问题? - 知乎 LISP路由器

  3. (转)面试前必知Redis面试题—缓存雪崩+穿透+缓存与数据库双写一致问题

    背景:redis问题在面试过程中经常被问到,对于常见问题一定不能放过. 面试前必知Redis面试题—缓存雪崩+穿透+缓存与数据库双写一致问题 一.缓存雪崩 1.1什么是缓存雪崩? 如果缓存数据设置的过 ...

  4. Web 技术人员需知的 Web 缓存知识(转)

    最近的译文距今已有4年之久,原文有一定的更新.今天踩着前辈们的肩膀,再次把这篇文章翻译整理下.一来让自己对web缓存的理解更深刻些,二来让大家注意力稍稍转移下,不要整天HTML5, 面试题啊叨啊叨的~ ...

  5. Web 技术人员需知的Web 缓存知识

    最近的译文距今已有4年之久,原文有一定的更新.今天踩着前辈们的肩膀,再次把这篇文章翻译整理下.一来让自己对web缓存的理解更深刻些,二来让大家注意力稍稍转移下,不要整天HTML5, 面试题啊叨啊叨的~ ...

  6. Web开发人员需知的Web缓存知识

    最近的译文距今已有4年之久,原文有一定的更新.今天踩着前辈们的肩膀,再次把这篇文章翻译整理下.一来让自己对web缓存的理解更深刻些,二来让大家注意力稍稍转移下,不要整天HTML5, 面试题啊叨啊叨的~ ...

  7. Android必知必会--GreenDao缓存

    Github版 CSDN版 本篇文章不是介绍GreenDao的配置和基础使用,记录一下GreenDao缓存的问题,帮助遇到同样问题的朋友找到原因和方法,下面是示例: 场景重现 //第一次查询 List ...

  8. 面试前必知Redis面试题—缓存雪崩+穿透+缓存与数据库双写一致问题

    今天来分享一下Redis几道常见的面试题: 如何解决缓存雪崩? 如何解决缓存穿透? 如何保证缓存与数据库双写时一致的问题? 一.缓存雪崩 1.1什么是缓存雪崩? 回顾一下我们为什么要用缓存(Redis ...

  9. Web 开发人员需知的 Web 缓存知识

    今天踩着前辈们的肩膀,再次把这篇文章翻译整理下.一来让自己对web缓存的理解更深刻些,二来让大家注意力稍稍转移下,不要整天HTML5, 面试题啊叨啊叨的~~ 什么是Web缓存,为什么要使用它? Web ...

随机推荐

  1. Hadoop(3)-Hadoop介绍

    Hadoop三大发行版本 Hadoop三大发行版本:Apache.Cloudera.Hortonworks. Apache版本最原始(最基础)的版本,对于入门学习最好. Cloudera在大型互联网企 ...

  2. java应用:csv文件的读写

    csv数据特点: csv是文本格式,一行数据是一条记录,每个单元之间用“,”隔开.csv数据可以用Excel打开. 读写csv文件的主要程序如下所示: import java.io.BufferedR ...

  3. 第一次学习tornado小练习

    内容 这次是python的一个web框架,tornado,这个web框架在python的几个web框架中一个比较简单的web框架,刚开始接触python的时候就知道python有两个比较常用的web框 ...

  4. VGA 时序标准

    VGA 显示器扫描方式从屏幕左上角一点开始,从左像右逐点扫描,每扫描完一行,电子束回到屏幕的左边下一行的起始位置,在这期间,CRT 对电子束进行消隐,每行结束时,用行同步信号进行同步:当扫描完所有的行 ...

  5. app:showAsAction 和android:showAsAction

    app:showAsAction 它有三个可选项1.always:总是显示在界面上2.never:不显示在界面上,只让出现在右边的三个点中3.ifRoom:如果有位置才显示,不然就出现在右边的三个点中 ...

  6. WPF中的命令与命令绑定(二)

    原文:WPF中的命令与命令绑定(二) WPF中的命令与命令绑定(二)                                              周银辉在WPF中,命令(Commandi ...

  7. 使用sqoop将mysql中表导入hive中报错

    [hdfs@node1 root]$ sqoop import --connect jdbc:mysql://node2:3306/cm?charset-utf8 --username root -- ...

  8. jmeter之Synchronizing Timer的理解

    该功能类似loadrunner的集合点,一般按照jmeter的树形结构,放在需要设置集合点的请求之前,两个参数的意思,我们先看官网的解释: 大概意思就是: Number of Simulated Us ...

  9. Android OpenStreetMap(OSM) 使用 osmbonuspack 进行导航

    关于OpenStreetMap的介绍,国内还是很少,csdn上面有一篇,写的不错,我也就不再做重复的事情了. 这里贴出链接地址:http://blog.csdn.net/mad1989/article ...

  10. Qt C++ 并发,并行,多线程编程系列1 什么是并发

    什么是并发,并发往简单来说就是两个或多个独立的任务同时发生,在我们的生活中也是随处可见.如果把每个人都当作一个独立的任务,那每个人可以相互独立的生活,这就是并发. 在计算机的系统里面,并发一般有两种, ...