前言

之前看完了李智慧老师著的《大型网站技术架构-核心原理与案例分析》这本书,书中多次提起浏览器缓存的话题,恰是这几天生产又遇到了一个与缓存的问题,发现自己书是没少看,正经走心的内容却不多,这次就借着工作中遇到的问题,一并把与网页缓存相关的HTTP头部信息总结一番,一来总结给自己看,以便后期查阅;二来把自己的想法和园中朋友分享,互相指点,如此,岂不妙哉!!!

简单的总结来说,在HTTP中与网页缓存相关的HTTP头部信息分为以下三组:

  • Last-ModifiedIf-Modified-Since
  • ETagsIf-None-Match
  • ExpiresCache-Control

下面就分别对这三组HTTP头进行详细的说明和总结!

Last-Modified和If-Modified-Since

在HTTP中Last-ModifiedIf-Modified-Since都是用于记录页面最后修改时间的HTTP头信息,二者的区别如下:

  • Last-Modified是由服务器往客户端发送的HTTP头;
  • If-Modified-Since是由客户端往服务器发送的头。

所以,请牢牢记住上述基本知识点,这样才能工作中分析请求包时不会晕头转向。

如上图所示,用户通过浏览器第一次请求相关网页时,服务器会返回一个Last-Modified:Mon, 26 Apr 2019 13:22:17 GMT这样的请求头;当用户再次访问对应的网页时,浏览器会将服务器响应的Last-Modified值赋给If-Modified-Since,接下来,浏览器会带着If-Modified-Since:Mon, 26 Apr 2019 13:22:17 GMT这样的请求头去访问服务器应用。服务器收到请求后,会将这个对应网页的更新时间与If-Modified-Since进行比对以决定是返回304重定向码还是200成功码。

ETags和If-None-Match

通过上面的总结,我们知道Last-ModifiedIf-Modified-Since只能判断资源的最后修改时间,以此来决定是否使用缓存。而ETagsIf-None-Match则比较更高级一点。通过ETagsIf-None-Match,我们可以对资源的任何属性进行判断,以此判断是否使用缓存。同样的,我们也需要记住ETagsIf-None-Match的两个知识点:

  • ETags是由服务器往客户端发送的HTTP头;
  • If-None-Match是由客户端往服务器发送的头。

请求逻辑与Last-ModifiedIf-Modified-Since大致一样,不同之处就是在服务器端的判断。比如有些特定的场合下,一些静态的文件,可能会被频繁的更新,但是文件内容没有变化,这时候如果使用Last-modified,服务器端始终返回最新的内容给浏览器,而Etag是根据文件内容来的,如果内容没有变化的话,始终会让浏览器使用本地缓存的文件。所以,使使用ETag可以更好的避免一些不必要的服务器相应。

Expires和Cache-Control

添加Expires头能有效的利用浏览器的缓存能力来改善页面的性能,能在后续的页面中有效避免很多不必要的HTTP请求,WEB服务器使用Expires头来告诉Web客户端它可以使用一个组件的当前副本,直到指定的时间为止。例如:Expires:Thu,15 Apr 2019 20:00:00 GMT;这个告诉浏览器缓存有效性持续到2019年4月15日为止,在这个时间之内相同的请求使用缓存,这个时间之外使用HTTP请求。与上面说到的Last-ModifiedIf-Modified-SinceETagsIf-None-Match相比,是能够节省一点带宽的,因为可能会少发一次HTTP请求。

但是Expires有一个明显的缺点;由于返回的到期时间是服务器端的时间,这样存在一个问题,如果客户端的时间与服务器的时间相差很大,那么误差就很大,所以在HTTP 1.1版开始,使用Cache-Control:max-age=秒替代。如果Cache-ControlExpires同时存在,Cache-Control生效。

由于现在基本上都在使用Cache-Control,所以有必要对Cache-Control进行详细的总结一下。

  • Cache-Control的可缓存性:

    取值 说明
    public HTTP返回的时候在Heaher中设置Cache-Control的值为public。它代表,这个HTTP请求它返回的内容所经过的任何路径中,包括中间的一些HTTP代理服务器以及发出请求的客户端浏览器,都可以进行对返回内容的缓存操作
    private 发起请求的浏览器才能使用返回数据的缓存
    no-cache 可以在本地或者proxy服务器进行缓存,每次发起请求都要去服务器验证,服务器返回可以使用缓存,才可以真正使用本地缓存,任何节点都不能直接使用缓存
  • Cache-Control的有效期
    |取值|说明|
    |----|---|
    |max-age=seconds|最常用模式,表示过期的秒数|
    |s-maxage=seconds|只有在代理服务器才会生效,且代理服务器会优先使用s-maxage|
    |max-stale=seconds|它是发起请求方,主动去带着的header;在max-age过期后,但还在max-stale的有效期内,还可以使用过期的缓存,不需要去原服务器请求新的内容|

  • Cache-Control的其它取值
    |取值|说明|
    |----|---|
    |no-store|浏览器或者proxy服务器都不能存返回数据的缓存,永远都需要去服务器请求新的数据|
    |no-transform|主要用在proxy服务器,表示不要去随意改动返回的内容,比如压缩什么的|

总结

这些细小的知识点,平时很少主动去关注,但是真正到分析问题的时候,很多时候却是卡在这些细小的知识点上。还是那句话,细节决定成败!大的知识点,大的流程,大家都可以说出一二,但是一旦细化了,才知道自己有好多的不懂,有好多的说不清楚。只有退潮了,才知道谁在裸泳!!!

2019年7月21日 于内蒙古呼和浩特。

网页缓存相关的HTTP头部信息详解的更多相关文章

  1. Linux的ifconfig看到的信息详解

    Linux的ifconfig看到的信息详解 [root@localhost ~]# ifconfig eth0 Link encap:Ethernet HWaddr :::BF:: inet addr ...

  2. Spring Boot 2.x基础教程:进程内缓存的使用与Cache注解详解

    随着时间的积累,应用的使用用户不断增加,数据规模也越来越大,往往数据库查询操作会成为影响用户使用体验的瓶颈,此时使用缓存往往是解决这一问题非常好的手段之一.Spring 3开始提供了强大的基于注解的缓 ...

  3. redis.conf配置信息详解

    redis.conf配置信息详解 配置文件 # Redis 配置文件 # 当配置中需要配置内存大小时,可以使用 1k, 5GB, 4M 等类似的格式,其转换方式如下(不区分大小写) # # 1k =& ...

  4. HTTP协议请求信息详解

    通常HTTP消息包括客户机向服务器的请求消息和服务器向客户机的响应消息.客户端向服务器发送一个请求,请求头包含请求的方法.URI.协议版本.以及包含请求修饰符.客户信息和内容的类似于MIME的消息结构 ...

  5. HTTP协议的头信息详解

    转载地址:http://blog.csdn.net/guoguo1980/article/details/2649658 HTTP(HyperTextTransferProtocol)是超文本传输协议 ...

  6. IE=edge,chrome=1的META信息详解

    这几天在玩 HTML5 ★ Boilerplate,注意到meta信息中有这么一句: 复制代码 代码如下: <meta http-equiv="X-UA-Compatible" ...

  7. linux系统/var/log目录下的信息详解

    一./var目录 /var 所有服务的登录的文件或错误信息文件(LOG FILES)都在/var/log下,此外,一些数据库如MySQL则在/var/lib下,还有,用户未读的邮件的默认存放地点为/v ...

  8. 缓存varnish的管理及配置详解

    一 工作原理 在当前主流的Web服务架构体系中,Cache担任着越来越重要的作用.常见的基于浏览器的C/S架构,Web Cache更是节约服务器资源的关键.而最近几年由FreeBSD创始人之一Kamp ...

  9. (网页)Java日志记录框架Logback配置详解(企业级应用解决方案)(转)

    转自CSDN: 前言 Logback是现在比较流行的一个日志记录框架,它的配置比较简单学习成本相对较低,所以刚刚接触该框架的朋友不要畏惧,多花点耐心很快就能灵活应用了.本篇博文不会具体介绍Logbac ...

随机推荐

  1. .NET错误提示之:无法更新EntitySet“TableName”因为它有一个DefiningQuery

    使用LINQ 进行提交数据时发生的错误提示 原因:提交的对象表 没有设主键.

  2. 更换Qt QtEmbedded库的版本出现问题及解决(交叉编译OpenSSL)

    近日将QtEmbedded库的版本由4.7.0更新到4.7.4.工具链并未改变,仍为 Target: arm-none-linux-gnueabiConfigured with: ......Thre ...

  3. Editor.md v1.4.2 发布,改进自定义工具栏

    分享 <关于我> 分享  [中文纪录片]互联网时代                 http://pan.baidu.com/s/1qWkJfcS 分享 <HTML开发MacOSAp ...

  4. ubuntu QT开发环境(三种方法安装Qt4.8,其中apt-get方法安装QT库最简单)good

    方法一 QT4.8.0库+QT Creator 2.4.1 特别声明:此方法极其耗时间,看电脑性能了.配置configure可减少编译时间 1.下载Qt .进入网址http://qt.nokia.co ...

  5. Java基础(二) 基本类型数据类型、包装类及自动拆装箱

    我们知道基本数据类型包括byte, short, int, long, float, double, char, boolean,对应的包装类分别是Byte, Short, Integer, Long ...

  6. Python连载8-datetime包函数介绍

    一.datetime包(上接连载7内容) 1.函数:datetime (1)用法:输入一个日期,来返回一个datetime类​ (2)格式:datetime.datetime(年,月,日,hour=, ...

  7. mvc中Scripts.Render的用法

    第一次接触新的东西,都会很陌生,但是时间久了就熟悉了变简单了. 视图文件中使用Scripts.Render()输出脚本包,Styles.Render()输出样式包 上面两张图是我所做项目里的,放上面会 ...

  8. Java多线程同步工具类之CountDownLatch

    在过去我们实现多线程同步的代码中,往往使用join().wait().notiyAll()等线程间通信的方式,随着JUC包的不断的完善,java为我们提供了丰富同步工具类,官方也鼓励我们使用工具类来实 ...

  9. 高并发 Nginx+Lua OpenResty系列(5)——Lua开发库Redis

    Redis客户端 lua-resty-redis是为基于cosocket API的ngx_lua提供的Lua redis客户端,通过它可以完成Redis的操作.默认安装OpenResty时已经自带了该 ...

  10. PWN菜鸡入门之函数调用栈与栈溢出的联系

    一.函数调用栈过程总结 Fig 1. 函数调用发生和结束时调用栈的变化 Fig 2. 将被调用函数的参数压入栈内 Fig 3. 将被调用函数的返回地址压入栈内 Fig 4. 将调用函数的基地址(ebp ...