资讯专栏INFORMATION COLUMN

「MISC」HTTP 缓存控制

RancherLabs / 2944人阅读

摘要:但这两个响应头不是为了控制缓存,而是为了确认修改的资源的一致性。所以就产生了下面更加高级的缓存控制方法第三第四项方法。过期控制指定相对于请求时间的过期时间,以秒为单位。在的值前如果有则表示这是一个弱。表示要求上传的文件在服务器上不存在。

现在的Web应用越来越复杂,体验越来越好。相应的,资源文件也越来越大,如果能让客户端在资源没更新的情况下,直接取用缓存的数据,那么不仅资源加载的更快,服务器压力更小,也为绿色地球做出了一份贡献。

程序员向来是追求最优,在设法缓存静态资源以后,大家又找到了一些方法来缓存动态生成的内容。看来程序员们都是环境保护主义者(笑。

从HTTP/1.0-HTTP/1.1,一共产生了3种控制缓存的方法:

Expires(响应头,HTTP/1.0)

Cache-Control(响应头,HTTP/1.1)

- Last-Modified(响应头),If-Modified-Since(请求头)
- Etag(响应头),If-None-Match(请求头)

以上就是HTTP控制缓存的方法。

除了这些,在第二个还有If-Unmodified-Since,第三个还有If-Match。但这两个响应头不是为了控制缓存,而是为了确认修改的资源的一致性。之后会介绍。

HTTP/1.0 Expires
Expires: 

其中 的格式如下:

Date: ,    :: GMT
Example: Fri, 03 Nov 2017 03:22:39 GMT

当设置了Expires后,客户端在此日期之前都不会去请求服务器,而是直接从缓存中取。
不过这样也有一个问题:如果完全不去请求服务器的话,在资源过期之前如果资源有更新,客户端还是使用着之前的资源。所以就产生了下面更加高级的缓存控制方法(第三、第四项方法)。

不过还有一个方法能解决这个问题:将资源的Expires设置为一个足够长的时间,而资源名为资源的Hash值,这样资源更新了以后,也使用的是不同的名称。那么就不存在上面的问题了。

HTTP/1.1 Cache-Control

Expires只能设置具体的日期,这样的话,如果客户端与服务器的时间不一致,会导致缓存时间不正确,还有可能直接导致缓存失效。

HTTP/1.1的Cache-Control配合If-Modified-Since或If-None-Match则完美的解决了这个问题。

Cache-Control比较常用的指令如下:

可缓存性

public: 响应可被任意缓存

private: 响应只能被客户端缓存,不能被中间节点(代理、CDN等)缓存

no-cache: 中间节点必须向原始服务器去验证缓存有效性。如果本身是原始服务器,则向自己确认

only-if-cached: 中间节点直接使用已存在的缓存来确认有效性,不向原始服务器确认。若本身是原始服务器,则此指令没有效果。

过期控制

max-age=: 指定相对于请求时间的过期时间,以秒为单位。

再验证

must-revalidation: 缓存过期后必须向服务器确认缓存是否有效

其他

no-store: 忽略缓存的存在,直接向服务器请求最新的资源。

上面列表中向服务器确认缓存是否有效的技术手段就是下文介绍的 Last-Modified/If-Modified-SinceETag/If-None-Match

Last-Modified / If-Modified-Since
Last-Modified: 

Last-Modified头是服务器告诉客户端此资源的最后修改时间,客户端则会将资源和这个时间都储存起来。之后,根据Cache-Control的指令,如果需要同服务器确认资源的有效性的时候则会将这个时间放在If-Modified-Since头中,供服务器进行比较,是返回304还是200。

If-Modified-Since头只会在GET和HEAD请求被附加进请求头。

If-Unmodified-Since
If-Unmodified-Since: 

一般来说在PUT, POST等方法使用,表示该次请求更新的资源的日期为,如果服务器检测到现存资源的日期不为(即已经被其他的方式更新了),则会失败并返回412。

ETag / If-None-Match
ETag: W/""
ETag: ""
If-None-Match: ""[, ""...]
If-None-Match: W/""[, ""]

如果将上面的 Last-Modified / If-Modified-Since 应用在动态的数据上的话,基本上没有可行性。那么就有了此方式的缓存。

在第一次请求的时候,服务器会附带ETag头。ETag的值是根据响应的内容来进行生成的,一般来说是内容(+其他一些标识的)哈希值。之后,根据Cache-Control的指令,如果需要同服务器确认资源的有效性的时候则会将这个etag_value放在If-None-Match头中,供服务器进行比较,是返回304还是200。

在ETag的值前如果有W/则表示这是一个弱Etag。弱ETag相等意味着这两个内容语义上是相等的,强ETag相等则表示内容每一个字节都相等。

举个弱ETag的例子:返回的数据中带有log信息,而两次返回的数据是相同的,log不同。

还有一种语法:If-None-Match: *,基本上用在PUT, POST等上,用于上传。表示要求上传的文件在服务器上不存在。

If-Match
If-Match: ""[, ""...]
If-Match: W/""[, ""]

对于GET, HEAD等请求,如果资源的ETag匹配上If-Match的值,则返回资源,否则返回412。
对于PUT, POST等请求,如果现有资源的Etag匹配上If-Match的值,那么进行写操作,否则失败返回412。

----- 记得点赞 -----

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/51457.html

相关文章

  • Nacos系列:Nacos的Java SDK使用

    摘要:发布配置支持程序自动发布配置,创建和修改配置使用同一个方法,配置不存在则创建配置已存在则更新。示例源码项目代码已上传至码云和上,欢迎下载学习参考资料用户指南的推荐阅读系列欢迎来到的世界系列基于的注册中心系列基于的配置中心 Maven依赖 Nacos提供完整的Java SDK,便于配置管理和服务发现及管理,以 Nacos-0.8.0 版本为例 添加Maven依赖: com.al...

    LinkedME2016 评论0 收藏0
  • IntegerCache

    摘要:类实际上是中中的缓存类,目的是节省内存消耗,提高程序性能。而当堆内存中的对象存储非常多时,就有可能造成内存泄漏。使用频率高创建对象也就越多,堆内存中的对象也就越多,所以也就会可能发生上述中的内存溢出等问题。 面试题:问以下代码输出的结果是多少? public class IntegerTest { @Test public void test() { ...

    yiliang 评论0 收藏0
  • Java 中的伪共享详解及解决方案

    摘要:对于伪共享的传统解决方案微信公众号技术栈以上使用此方法的某个版本对伪共享做了优化以下使用此方法中的解决方案中已经提供了官方的解决方案,中新增了一个注解。 1. 什么是伪共享 CPU 缓存系统中是以缓存行(cache line)为单位存储的。目前主流的 CPU Cache 的 Cache Line 大小都是 64 Bytes。在多线程情况下,如果需要修改共享同一个缓存行的变量,就会无意中...

    BenCHou 评论0 收藏0

发表评论

0条评论

RancherLabs

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<