[HTTP 学习笔记] HTTP缓存控制

HTTP缓存控制

本文部分内容摘抄其他博客、文章,仅用于学习HTTP缓存控制
如有错误,欢迎批评指正

对于Web站点来说,资源来自于网络下载,在下载过程中,如果遇到延迟或者网络堵塞,会导致资源加载速度过慢,影响用户的体验。另一方面,如果每次访问都从服务器下载重复资源,会给服务器带宽带来不必要的浪费,因此通过缓存重用已经获取的资源,可以有效的提高Web站点的响应及减少服务器压力。以下就来学习HTTP缓存控制。

HTTP报文中与缓存相关的首部字段

首先,先了解一些与缓存相关的首部字段。

  • 通用首部字段
字段名称 说明
Cache-Control 控制缓存的行为
Progma HTTP1.0 ,值为"no-cache"时禁用缓存
  • 请求首部字段
字段名称 说明
if-Match 比较Etag是否一致
If-None-Match 比较Etag是否不一致
if-Modified-Since 比较资源最后更新的时间是否一致
if-Unmodified-Since 比较资源最后更新的时间是否不一致
  • 响应首部字段
字段名称 说明
Etag 资源的匹配信息
  • 实体首部字段
字段名称 说明
Expires HTTP1.0,用于设置实体主体过期时间
Last-Modified 资源的最后一次修改时间

缓存控制

Pragma

HTTP1.0时代的字段,目前已很少使用,用于禁用缓存,通常设置为Pragma: no-cache,当设置该字段时,服务器会知会客户端不缓存该资源。当客户端请求带有此字段时,会表示客户端禁用缓存,需要下载资源。
例如我们常用的chrome开发者工具中,开启Disable cache时,客户端就会在所有请求中添加这个字段表示禁用缓存。

Prama:no-cache

Expires

HTTP1.0时代的字段,用于启用缓存及定义缓存时间。该字段的值对应绝对时间:格林尼治时间(GMT)。该时间用于告诉客户端资源缓存过期的时间,如果没有超过该时间点,则发送的请求不需要向服务器访问,直接使用缓存的资源。需要注意的是该字段的时间相对于服务器时间而言的。

Expires:Mon, 15 May 2017 02:34:13 GMT

Cache-Control

由于Expires字段的时间是相对服务器的,在系统时间不准确不统一时,可能会有异常的情况,HTTP1.1中新增了Cache-Control头用于区分缓存机制,通过它提供的不同值来定义具体的缓存策略。

该首部的值可以采用组合的形式,需要注意部分限制,比如no-cache不能不能和 max-age、min-fresh、max-stale 一起搭配使用:

Cache-Control: public, max-age = 3600

// 表示任何情况下都得缓存资源,缓存时间为1小时,后续1小时内,用户访问该资源都无需发送请求

需要注意几个首部的优先级:Pragma > Cache-Control > Expires

  • 作为请求首部时,value可选值有:
字段名称 说明
no-cache 告知(代理)服务器不直接使用缓存,要求向原服务器发起请求
no-store 所有内容都不会保存到缓存或者Internet临时文件中
max-age=delta-seconds 告知服务器,客户端希望接收一个存在时间(Age)不大于delta-seconds 秒的资源
max-stale[=delta-seconds] 告知(代理)服务器客户端愿意接收一个草果缓存时间的资源,若有定义delta-seconds则为delta-seconds秒,若没有则为任意超出时间
min-fresh=delta-seconds 告知(代理)服务器客户端希望接收一个在小雨delta-seconds秒内被更新过的资源
no-transform 告知(代理)服务器客户端希望获取实体数据没有被转换(比如压缩)过的资源
only-if-cached 告知(代理)服务器客户端希望获取缓存的内容(若有),而不用向原服务器发去请求
cache-extension 自定义扩展值,若服务器不识别该值将被忽略掉
  • 作为响应首部时,value可选值有:
字段名称 说明
public 表明任何情况下都得缓存该资源(即使是需要HTTP认证的资源)
Private[="field-name"] 表明返回报文中全部或部分(若制定了field-name 则为field-name 的字段数据)仅开放给某些用户(服务器制定的share-user,如代理服务器)做缓存使用,其他用户不能缓存这些数据
no-cache 不直接使用缓存,要向服务器发起(新鲜度校验)请求
no-store 所有内容都不会被保存到缓存或Internet临时文件中
no-transform 告知客户端缓存文件时不得对实体数据做任何改变
only-if-cached 告知(代理)服务器客户端希望获取缓存的内容(若有),而不用向原服务器发起请求
must-revalidate 当前资源一定是向原服务器发去验证请求的,若请求失败会返回504(而非代理服务器上的缓存)
proxy-revalidate 与must-revalidate类似,但仅能应用于共享缓存(如代理)
max-age=delta-seconds 告知客户端该资源在delta-seconds秒内是新鲜的,无需向服务器发请求
s-maxage=delta-seconds 同max-age,但仅应用于共享缓存(如代理)
cache-extension 自定义扩展值,若服务器不识别该值将被忽略

Last-modified

该字段用于为资源标记一个最后修改时间,服务器可以在向客户端发送资源时,将资源最后修改时间以“Last-Modified: GMT”的形式加在实体首部上一起返回给客户端。
客户端在接收到包含字段的响应时,会为该资源标记该信息,并下一次请求该资源时,会把该信息负在请求报文中(字段为If-Modified-Since: Last-Modified-value)一起发送给服务器,当该时间与服务器上最后修改时间一致时,则说明资源未被修改。通过这个判断,服务器应当返回304状态码和响应报头,内容为空,以达到节省宽带的目的。
如果服务器发现未匹配到(资源最后更新时间变更了),则应当返回412状态码给客户端。Last-Modified 存在一定问题,如果在服务器上,一个资源被修改了,但其实际内容根本没发生改变,会因为Last-Modified时间匹配不上而返回了整个实体给客户端(即使客户端缓存里有个一模一样的资源)。

Last-modified: Fri, 22 Jul 2016 01:47:00 GMT

Etag

该首部字段通过服务器给资源标记唯一标识符(例如md5),在响应中返回客户端,客户端在下一次请求时附带Etag字段,服务器即可判断资源相对于客户端是否一致,决定是否返回新的资源,或通过304告知客户端使用缓存。
Etag字段与Last-Modified类似:

Etag: 5d8c72a5edda8d6a

// 
If-Match:Etag-value
// 匹配
If-None-Match:Etag-value
// 不匹配

需要注意Etag优先级高于Last-Modified

总结

对于HTTP缓存相关的内容分三种情况:

  1. 可储存:HTTP响应内容决定资源是否可以被客户端缓存。
  2. 期限:当客户端再次请求资源前通过Expires的绝对时间或Cache-Control的相对时间确认资源是否已经过期,当过期时才向服务端发起请求确认资源是否过期,
  3. 有效性比对:服务端通过比对请求中的最近修改时间、标识符等方式对资源有效情况的判断,决定缓存的资源是否需要更新。

Steve Sounders

对于经常更新的资源来说,HTTP缓存控制可能会带来一些麻烦,尤其是需要经常变动尽快更新线上的资源。为此Web开发者发明了一种名为Steve Sounders的技术。对于不频繁更新的文件,在其URL(通常为文件名)后面添加上一个版本号,每个版本号就成了一个独立资源,这样该资源即获得了长时间的缓存时长,同时又可以在需要时通过替换链接的方式使资源更新。在web开发大量使用自动化构建工具的今天,替换链接不再是一件麻烦事。

对于css及JS这种具有相互依赖关系的文件来说,使用这个技术,解决了更新资源时缓存文件更新不一致的问题。

<script src="xxx.js?version=12345"></script>
// 比如使用查询字符串

参考来源:
HTTP缓存控制小结
HTTP缓存

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,142评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,298评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,068评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,081评论 1 291
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,099评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,071评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,990评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,832评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,274评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,488评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,649评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,378评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,979评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,625评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,796评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,643评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,545评论 2 352

推荐阅读更多精彩内容