我们经常通过缓存技术来加快网站的访问速度,从而提升用户体验。HTTP协议中也规定了一些和缓存相关的Header,来允许浏览器或共享高速缓存缓存资源。这些Header包括:

  • Last-Modified 和 If-Modified-Since
  • ETag 和 If-None-Match
  • Expires
  • Cache-Control

  以上Header又可以分成两种类型:

  • 协商缓存:浏览器发送验证到服务器,由服务器决定是否从缓存中读取,如 1 和 2 。
  • 强缓存:浏览器验证缓存的有效性,然后决定是否从缓存中读取数据,如 3 和 4 。

  本文将会分别介绍这四种配置的作用以及可能产生的影响。

  1、Last-Modified 和 If-Modified-Since

  Last-Modified:服务器在响应请求时,告知浏览器资源的最后修改时间。

  If-Modified-Since:浏览器再次发送请求时,会通过此Header通知服务器在上次请求时所得到的资源最后修改时间。服务器会将If-Modified-Since与被请求资源的最后修改时间进行比对。若资源的最后修改时间晚于If-Modified-Since,表示资源已被改动,则响最新的资源,返回200状态码;若资源的最后修改时间早于或等于If-Modified-Since,表示浏览器端的资源已经是最新版本,响应304状态码,通知浏览器继续使用缓存中的资源。

  2、ETag 和 If-None-Match

  ETag:服务器分配给资源的唯一标识符,资源被修改后,ETag也会随之发生变化。

  If-None-Match:浏览器再次发送请求时,会通过此Header通知服务器已缓存资源的ETag。服务器会将If-None-Match与被请求资源的最新ETag进行比对。若不相同,表示资源已被改动,则响应最新的资源,返回200状态码;若值相同,则直接响应304状态码,通知浏览器继续使用缓存中的资源。

  3、Expires

  服务器可以通过此Header向浏览器传递一个具体的时间(格林威治格式,例如:Thu, 19 Jul 2018 07:43:05 GMT) ,来明确地宣告资源的有效期。在资源过期之前,浏览器不再发送请求,而是直接从缓存中读取数据。只有当资源过期之后,浏览器才会再次向服务器请求该资源。

  4、Cache-Control

  服务器使用此Header来向客户端建议缓存策略,它有一下几个可选值:

  max-age=秒:告知浏览器缓存的有效时长,在该时间内浏览器将直接从缓存中读取数据。

  s-maxage=秒:作用同max-age,但是只对共享高速缓存(如CDN)有效,对浏览器无效。

  no-cache:告知浏览器不要直接使用缓存,而是必须向服务器发送请求。

  no-store:告知浏览器不要缓存本次请求和响应的任何信息。

  public:宣告任何缓存媒介都可以缓存该响应。

  private:宣告该响应只允许个体客户端(如浏览器)去缓存,而不允许共享高速缓存(如CDN)去缓存。

  在上面的介绍中我们了解到浏览器会根据max-age设置的时间进行缓存。而通过研究发现CDN也会识别源站响应头中Cache-Control属性,根据max-age设置的时间进行缓存,但是,如果源站同时设置了s-maxage和max-age,那么CDN会优先采用s-maxage。

  下面通过图例来展示一下这些可选值的效果。

  首先了解一下浏览器是怎样根据max-age进行缓存的:

从上图不难发现,服务器在Header中返回了Cache-Control: max-age=100后,浏览器成功缓存100秒,该时间段内的请求都从直接以本地缓存来响应。

  那么,服务器在Header中返回Cache-Control:s-maxage=100时,又会对浏览器产生什么样的影响呢?

  如上图所示,浏览器没有采取任何缓存策略,这是因为s-maxage面向的是共享高速缓。

  上面这两个例子很容易理解,在现实世界中,为了加快网站响应速度,我们可能会在浏览器和服务器之间引入CDN服务。浏览器的请求会先到达CDN,然后CDN判断是从缓存中读取数据还是回源到服务器。接下来,让我们看看max-age和s-maxage会对CDN的缓存策略带来哪些影响。

  可以看出CDN也会利用max-age来缓存,所以在100秒内强制刷新浏览器时,CDN会直接用缓存来响应。

  如果服务器使用了s-maxage又会如何呢?

  不难发现CDN对max-age和s-maxage采取了同样的缓存策略,但浏览器并不会根据s-maxage来进行缓存。

  CDN供应商的特殊规则

  我们分别测试了阿里云和腾讯云的CDN对Cache-Control的支持情况,发现他们都有一些独特的规则。

  阿里云CDN可以在控制台里设置Cache-Control,该设置会覆盖源服务器的Cache-Control。

  腾讯云CDN虽然没有再控制台提供覆盖Cache-Control的功能,但其规则却一点也不简单,在使用的时候一定要特别注意:

  • 服务器和CDN均不对缓存进行配置时,CDN会采用默认的缓存机制(静态文件缓存30天,动态请求不缓存);
  • CDN配置缓存机制(但并未开启高级缓存配置)且服务器设置Cache-Control: s-maxage=200,max-age=100时,CDN会按照其控制台设置的规则进行缓存,浏览器则按照max-age进行缓存;
  • 服务器不设置Cache-Control时,CDN会自动在响应的Header中添加Cache-Control: max-age=600,这就会让浏览器将该资源缓存600秒;
  • 服务器设置为禁用缓存时,CDN和浏览器均不进行缓存;
  • 服务器设置Cache-Control: s-maxage=200,max-age=100并开启CDN的高级缓存配置时,CDN会从s-maxage和控制台中设置的缓存时间中选择最小值来作为缓存时间,而浏览器则始终使用max-age;
  • 服务器设置Cache-Control:max-age=100并开启CDN的高级缓存配置时,CDN会从max-age和控制台中设置的缓存时间中选择最小值来作为缓存时间,不影响浏览器的缓存策略。

  组合使用

  如果同时设置了这些Header,浏览器和高速共享缓存会按照下面的优先级进行缓存:

  Cache-Control > Expires > ETag > Last-Modified

  也就是说,Cache-Control不仅是强缓存,而且拥有最高的优先级,我们可以为不经常发生变化的资源应用该Header来提升响应时间。

  在Ada中使用缓存

  Ada提供了UI脚手架和API脚手架,这两类脚手架的服务器端入口文件分别为index.server.js和index.js,我们只需要在入口文件的请求处理函数中为响应添加适当的Header,即可通知客户端进行响应的缓存,比如:

  // 设置CDN缓存300秒,浏览器缓存200秒

  ctx.response.headers.set('Cache-Control', public,s-maxage=300,max-age=200)

  在为请求添加缓存Header之前,应该先为其制定适当的缓存策略,需要考虑该URL是否适合缓存(数据是否特定于用户)以及需要缓存的时长等等。

  总结

  通过使用这些HTTP Header,我们可以主动影响浏览器甚至CDN的缓存策略,从而减少请求数量,提升网页性能,减轻服务器压力。

  Ada的灵活机制能让我们为不同的URL设置不同的缓存策略,能够更有针对性地进行主动缓存。

通过HTTP Header控制缓存的更多相关文章

  1. servlet 的控制缓存时间和response的重定向

    //控制缓存时间 public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletE ...

  2. HTTP之如何控制缓存

    HTTP控制缓存的能力 ===================摘自<HTTP权威指南>==================================== 服务器可以通过HTTP定义的 ...

  3. 缓存Cache

    转载自  博客futan 这篇文章将全面介绍有关 缓存 ( 互动百科 | 维基百科 )cache以及利用PHP写缓存caching的技术. 什么是缓存Cache? 为什么人们要使用它? 缓存 Cach ...

  4. PHP-Header缓存策略

    Expires.Cache-Control.Last-Modified.ETag 是RFC 2616(HTTP/1.1)协议中和网页缓存相关的几个字段.前两个用来控制缓存的失效日期,后两个用来验证网页 ...

  5. WCF4.0 –- RESTful WCF Services

    转自:http://blog.csdn.net/fangxinggood/article/details/6235662 WCF 很好的支持了 REST 的开发, 而 RESTful 的服务通常是架构 ...

  6. 重新想象 Windows 8.1 Store Apps (90) - 通信的新特性: 通过 HttpBaseProtocolFilter 实现 http 请求的缓存控制,以及 cookie 读写; 自定义 HttpFilter; 其他

    [源码下载] 重新想象 Windows 8.1 Store Apps (90) - 通信的新特性: 通过 HttpBaseProtocolFilter 实现 http 请求的缓存控制,以及 cooki ...

  7. 通过HTTP头控制浏览器的缓存

    通过HTTP头控制浏览器的缓存 浏览器缓存是提高用户体验和提升程序性能的一个很重要的途径,通过浏览器的缓存控制,可以对实时性要求不高的数据进行缓存,可以减少甚至不需要再次对服务器的请求就可以显示数据. ...

  8. php如何控制客户端生成缓存

    php如何控制客户端生成缓存 一.总结 一句话总结:用http消息响应头中的Cache-Control来控制客户端缓存,说的是页面本身被客户端缓存,而不是重新生成的其它的非页面缓存 响应头Cache- ...

  9. 网页的缓存Cache与控制

    什么是缓存 Cache? 缓存位于客户端与服务器之间, 或者服务器与服务器之间.它决定是否保存所获资源的副本,以及如何使用副本,何时更新副本,这里所说的资源包括页面的HTML, 图片,文件等等. 使用 ...

随机推荐

  1. Extended paging tables to map guest physical memory addresses from virtual memory page tables to host physical memory addresses in a virtual machine system

    A processor including a virtualization system of the processor with a memory virtualization support ...

  2. gdal以GA_Update方式打开jpg文件的做法

    作者:朱金灿 来源:http://blog.csdn.net/clever101 gdal库是不支持以GA_Update方式打开jpg文件的,原因在于gdal_1_10_1\frmts\jpeg文件夹 ...

  3. java-线程-ABCABC

    public class OneByOne { private Lock lock = new ReentrantLock(); private Condition conditionA = lock ...

  4. 监控Nginx服务的Shell脚本

    Nginx 虽然处理并发量比 apache 确实要强点,但它这种 php-cgi 模式不是太稳定,这点网上也有朋友总结了,我在实现项目中也感受到了. 我们一台支付机,偶尔会出现以下情况的:php-cg ...

  5. Google Android Studio Kotlin

    Google Android Studio Kotlin 开发环境配置 Google 近日开发者大会宣布Kotlin成为Android开发的第一级语言,即Android官方开发语言,可见Google对 ...

  6. C语言检查本机公网IP并发送邮件

    这是一个用来获取本机公网IP地址,并检查是否是配置里保存的IP地址,假设不是,就向指定的邮箱发送一个邮件,报告这个IP地址的一段小代码.放到开机启动中,电脑不设password的时候万一丢了,还能有个 ...

  7. wxWidgets初学者导引(2)——下载、安装wxWidgets

    wxWidgets初学者导引全目录   PDF版及附件下载 1 前言2 下载.安装wxWidgets3 wxWidgets应用程序初体验4 wxWidgets学习资料及利用方法指导5 用wxSmith ...

  8. 设计模式在JDK中的应用

    在JDK(Java Development Kit)类库中,开发人员使用了大量设计模式. 创建型模式: (1) 抽象工厂模式(Abstract Factory) • java.util.Calenda ...

  9. Python: 图像处理的基本运算

    Python 作为一种面向对象.直译式的计算机程序语言,在很多领域得到广泛应用. 本文主要介绍 Python 在图像处理中的基本运算,借助 scikit-image 库,Python 在做图像处理的 ...

  10. TCP/IP协议族(一)

    TCP/IP协议族(一) HTTP简介.请求方法与响应状态码 接下来想系统的回顾一下TCP/IP协议族的相关东西,当然这些东西大部分是在大学的时候学过的,但是那句话,基础的东西还是要不时的回顾回顾的. ...