热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

关于前端:你不知道的浏览器缓存

其实对于浏览器缓存的内容网上曾经举不胜举,之所以产出本文的目标是,遇到缓存相干的问题后,在网上看到的所有相干内容大都雷同对细节的形容都不够全面甚至有误。因而浏览了缓存相干的RFC文档及浏览器内核的实现文档等对缓存相干内容进行整顿。

引言

其实对于浏览器缓存的内容网上曾经举不胜举,之所以产出本文的目标是,遇到缓存相干的问题后,在网上看到的所有相干内容大都雷同对细节的形容都不够全面甚至有误。因而浏览了缓存相干的RFC文档及浏览器内核的实现文档等对缓存相干内容进行整顿。

在理解浏览器缓存之前,咱们无妨先谈谈缓存的意义。这里援用RFC文档上的一句话:缓存如果不能用以晋升性能,那么它就毫无用处。以HTTP缓存为例,如果缓存未过期那么就缩小了网络申请,如果缓存通过验证那么就缩小了传输资源大小。而对于过期与验证机制的解说将在下文中开展。

顺便一提,本文具体的给出了参考链接以便阅读者对其中任何一个局部感兴趣时能够找到更加具体的参考资料。


浏览器缓存概述

浏览器缓存能够从多个维度进行形象分类。在狭义上来讲无论是memory cache、service worker、push cache、http cache都属于浏览器缓存的概念,而大部分时候咱们提到浏览器缓存的概念往往是指http cache。其实对于浏览器而言还有一种回退缓存(page cache),

以下咱们来关注几种浏览器可能会产生缓存的场景:

  • 资源预加载: 如preloader ,preload、prefetch。preloader与preload不同是资源预加载期,例如在标记化时,可能须要的css资源就曾经被事后加载到memory cache中了。而资源预加载技术,通过link实现。能够将我的项目中可能用到的数据先申请过去以备页面应用。数据寄存于内存缓存( memory cache)。参考:https://calendar.perfplanet.com/2013/big-bad-preloader/
  • 服务端推送: 这里是指http2的服务端推送,而非客户端轮询。是一种服务器依据某种规定推送客户端将可能用到的资源来缩小申请工夫的技术。数据寄存于push cache。推送缓存中的数据仅能够应用一次,之后将可能依据协定头存在于http缓存中。参考:https://jakearchibald.com/2017/h2-push-tougher-than-i-thought/
  • service worker: Service workers 实质上充当 客户端与服务端之间的代理服务器。这个 API 创立了无效的离线体验,它会拦挡网络申请并依据网络是否可用采取来适当的动作、更新来自服务器的的资源。它还提供入口以推送告诉和拜访后盾同步 API。server woker的缓存不同于http 缓存,由server worker本身接管,存储在server worker 参考:https://w3c.github.io/ServiceWorker/#cache-objects
  • 反复的网络资源申请: 常见的网络资源申请,能够依据协定头将资源存储在硬存中,以备下一次应用(http cache),绝对于内存缓存,能够进行长久化的存储,而不会局限于单次会话。参考:https://www.rfc-editor.org/rfc/inline-errata/rfc7234.html
  • 页面回退:设想有这样一种场景,你点进了一个博客,顺着博客的链接你进了另一篇文章,当你回退的时候是否会感觉上一个页面仿佛很快就会退了而非从新进行了一遍加载。这就是浏览器为了浏览器性能实现的页面回退机制(Page Cache)。不过此种机制往往不存在于页面内资源寻找的过程,是一种浏览器本身不受开发者管制的实现机制。
    参考:https://calendar.perfplanet.com/2013/big-bad-preloader/

以上缓存的读取程序为: (Memory Cache/Preload Cache) -> Service Worker -> (Disk Cache/HTTP cache) -> Push Cache

而本文次要以Http Cache的形容为主,对于Service worker以及Server Push如果感兴趣能够通过参考链接进行过理解。


HTTP缓存概述

缓存的指标是通过重用先前的响应音讯以满足以后申请,来显着进步性能。

让咱们来看一个小例子以便于了解:
这天浏览器申请一个叫做海绵宝宝.jpg的资源,服务器给了浏览器一张图片。当浏览器再一次申请服务器海绵宝宝.jpg时,
服务器说:大哥,将来30天图都不会变,你就不能存起来下次别来管我要了吗?我太累了。并在响应里写到,这个图30天都不变。
于是浏览器在这30天里遇到这张图的申请都会应用缓存的图片以响应。
第31地利,浏览器又遇到了海绵宝宝.jpg的申请。于是他问服务器:海绵宝宝.jpg变了吗
服务器答道:没变
又过了一段时间,遇到这个申请时浏览器又去问服务器
服务器说:变了。并给了浏览器一张图片。
浏览器这次就用新的图片响应了申请。

记住本文的配角:浏览器和海绵宝宝.jpg,咱们将在后文多处看到他们。(是的,服务器在本文只是主角)
前情提要:在前面咱们会讲述:

  • 服务器如何告知图片资源海绵宝宝.jpg的有效期
  • 浏览器如何计算图片是否过期(要晓得这图片是服务器转交给浏览器的)
  • 服务器如何依据信息得悉浏览器的资源是不是无效的(毕竟服务器不止和一个浏览器对话,无奈记忆只能计算)
  • 如果某次,服务器没有告知海绵宝宝.jpg这张图片资源的过期信息,浏览器还会存储资源吗
  • 浏览器的缓存中可能有很多张海绵宝宝.jpg资源吗,如果有会怎么抉择呢
  • 浏览器会如何缓存海绵宝宝.jpg(要晓得浏览器要解决很多申请,除了海绵宝宝.jpg,可能还有派大星.jpg,他们须要被辨别)

简略的来说当咱们申请一个申请一个本地存在响应缓存的资源时,浏览器并不会立刻发动网络申请。而是对缓存的新鲜度(freshness)进行一个断定,如果该响应是能够应用的,那么就会间接应用缓存资源以缩小提早和网络开销)。

如果缓存资源曾经古老了,那么就会对缓存资源进行验证。如果验证通过,那么浏览器依然能够复用资源,以缩小网络传输的资源大小。如果没有通过,则源服务器该当在验证申请中返回资源,而不是仅仅通知浏览器该缓存不可应用。

强缓存与协商缓存:当初的许多材料中都将未过期可间接应用的缓存称为强制缓存。过期了须要验证的缓存称为协商缓存。然而实际上RFC文档中并未给出这样的定义。也就是说这两个概念属于了解性的概念而非规范性的概念

为了简略了解能够先参考上面这张图。然而这里隐去很多细节,随着后文对内容的一直裁减,咱们会欠缺这张图。

以上简述,形容了网络资源申请应用缓存的一个大抵过程。以下将详细描述过期验证机制。


过期机制

还记得下面海绵宝宝图片的例子吗,咱们当初须要来解决第一个问题,即服务器如何告知图片资源海绵宝宝.jpg的有效期。为了解决这个问题,则须要一种标准来明确定义如何阐明进行资源缓存机制。这种标准必须是单方都能够了解的。在HTTP1.1中,能够应用Cache-Control的缓存指令,以实现缓存机制。

在应用浏览器决定对一个内容进行缓存之前,他将会断定内容是否为能够缓存的。

  • 如果缓存指令被设置为no-store,则不能够应用缓存
  • 如果缓存指令被设置为private,则不能够应用作为共享缓存。即代理服务器不能够对资源进行缓存。
  • 除非响应中明确蕴含缓存字段,否则不应该缓存Authorization首部字段的申请
  • 一般来说,响应如果既没有验证机制也没有过期机制,那么通常不缓存,不过并不会禁止这样的缓存行为

当资源缓存之后,则在重用时须要断定资源是否过期。max-age被用以设置缓存存储的最大周期,超过这个工夫缓存被认为过期(单位秒)。
对于共享缓存来说(比方各个代理),s-maxage将笼罩max-age或者Expires头,公有缓存会疏忽它。

因而服务器如果想要告知资是30天过期工夫,则须要设置:
Cache-Control: max-age=2592000

当初服务器胜利的设置了过期工夫,咱们来到第二个问题,浏览器如何计算资源过期了?
其实只须要保障资源的可缓存工夫大于资源的存在工夫,那么缓存就没有过期。反之,则缓存则过期了。以下咱们将探讨可缓存工夫(freshness LifeTime)与存在周期(Age)的具体算法。

freshness LifeTime的算法:

  • 如果缓存是共享的,如存在s-maxage则应用
  • 如果存在max-age响应指令,则应用其值
  • 如果存在Expires首部字段,则用它的值减去Date首部字段的值
  • 当响应中没有明确指出过期工夫。 将可能可能应用启发式freshness计算

还记得,咱们之前探讨的问题:如果没有约定缓存相干的内容,那么还会缓存吗?
答案是:不肯定。一般来说如果既没有过期阐明,也没有明确进行协商验证。那么不缓存。但不禁止缓存。可由浏览器自由发挥。个别这种自由发挥被称之为启发式缓存

对于启发式缓存的算法,通常采纳Last-Modified与Date时间差的1/10来作为freshness LifeTime。对于启发式缓存咱们有两点须要留神。

  • 启发式缓存是一个非规范性的行为,实现上会随着浏览器不同存在一些差别,也可能没有。标准上不禁止
  • 对于那些响应头中明确指出该如何缓存的资源,明确禁止应用启发式缓存

Age算法:
Age首部字段被用于形容一个缓存接管到响应音讯的估算时长(Age)。Age 字段的值是指音讯被源服务器创立或者验证之后以来缓存的秒数估算值。
重要的是,Age值是响应沿源服务器的门路驻留在每个缓存中的工夫的总和,并须要加上在网络门路中的传输工夫

以下数据被用于计算age

  • age_value: “age_value”以适宜算数运算的模式示意Age首部字段。如果不可用,则为0。
  • date_value: “ date_value”以适宜于算术运算的模式示意Date标头字段的值。
  • now: now示意时钟的以后值。应该应用ntp或一些相似的协定,使其工夫同步UTC工夫
  • request_time: 发动申请使得存储响应被触发的工夫
  • response_time: 收到响应时主机时钟的以后值

响应的age能够以两种齐全独立的形式计算

  • apparent_age:如果本地时钟与原始服务器的时钟是协调同步的,response_time减去date_value。 否则,后果将被替换为零
  • corrected_age_value:如果沿响应门路的所有缓存实现HTTP / 1.1,缓存必须绝对于启动申请的工夫来解释此值,而非收到响应的工夫

这里简略说下,为什么http1.1须要应用request工夫进行校对。因为http1.1的存储最大周期时间是绝对于申请的工夫的。

apparent_age = max(0, response_time - date_value);  
response_delay = response_time - request_time;  
corrected_age_value = age_value + response_delay

合并为

corrected_initial_age = max(apparent_age, corrected_age_value)

如果缓存对Age首部字段的值相信(例如,没有HTTP / 1.0 hops存在于Via首部字段中),则在这种状况下,corrected_age_value能够用作corrected_initial_age

存储响应工夫能够通增加存储响应最初一次被源服务器验证(以秒为单位)与corrected_initial_age的和值来计算

resident_time = now - response_time;  
current_age = corrected_initial_age + resident_time

看到这,可能会令人头秃。简略的总结一下:
Age 音讯头里蕴含对象在缓存代理中存贮的时长,以秒为单位。这里形容了Age首部字段的算法。
而缓存存在周期的算法则是:上一次收到服务器回答间隔当初的工夫的差值和在代理服务器中存贮的工夫之和。即缓存在浏览器存在的时长+缓存在代理服务器门路上存在的时长。

对于过期机制的三个首部字段别离为:

Cache-Cotrol:Cache-Control是缓存管制的重要字段,如果要零碎的理解它的各项指令,那么最好的形式是读RFC文档,或者MDN文档。本文不会详解cache-control的每个指令,而会去一些容易混同的点击进行概述。

  • 缓存指令是从多个维度形容缓存的。例如Cache-Control:public, max-age=31536000蕴含了资源的可缓存性以及过期个性。
  • no-cache不是禁用缓存,no-store才是。如果显式的应用了no-store,则浏览器不能应用启发式缓存。
  • 如果心愿缓存每次都应用验证机制,则能够应用no-cache,或者把max-age设置为0(如果是Expires,则能够把它设置为一个显然过期了的工夫)。

Expires:该字段提供了一个日期,在该日期之后的资源被认为是过期的。对于Expires须要留神的是:

  • 如果存在max-age,则该值被疏忽。
  • 如果共享缓存存在s-maxage,则该值被疏忽
  • 采纳极大值时,将可能导致问题(例如,因为对工夫值应用32位整数而导致时钟溢出)
  • 如果存在多个Expires字段,则被视为有效

Pragma:Pragma 是一个在 HTTP/1.0 中规定的通用首部,这个首部的成果依赖于不同的实现,所以在“申请-响应”链中可能会有不同的成果。它用来向后兼容只反对 HTTP/1.0 协定的缓存服务器,那时候 HTTP/1.1 协定中的 Cache-Control 还没有进去。

  • 当申请中没有 Cache-Control 头字段时,缓存必须将无缓存申请 pragma-directive 视为具备与“ Cache-Control: no-cache”存在时雷同的成果
  • 在发送无缓存申请时,客户机应该同时蕴含pragma和-control指令
  • no-cache这个指令不是规范性的,因而本计划不能牢靠代替Cache-Control

依据以上的过期机制,如果缓存被断定为未过期的,则能够在不与源服务器连贯的状况下间接应用缓存响应音讯。否则则该当应用验证机制。以下将开展讲述验证机制。


验证机制

上节中讲到了过期机制的断定。当一个资源过期,或者初始时就被设置为强制验证等起因导致缓存无奈提供响应时,它能够应用条件申请机制在转发申请到源服务器以抉择一个无效响应。这个过程被称为验证。对于条件申请机制如果你感兴趣能够参阅条件申请和分布式创作及版本控制

还记得上文海绵宝宝的例子吗?下来咱们将探讨第三个问题服务器如何验证缓存资源。值得一提的是在这个局部服务器化身配角了。

如果须要服务器可能疾速验证本地资源绝对于缓存资源的变更,咱们须要有一个标示帮忙服务器进行疾速比对。如果每次无效更新这个值都会变更,反之则不会变更,那么服务器就能疾速判断本地资源绝对于缓存资源是否有变更了。咱们将能够帮忙咱们验证的形式为验证器

在正式介绍验证器之前咱们无妨想想什么样的标示能够用于判断资源变更比对。
如果文件内容变更了,因而内容散列也会变更,反正内容散列则不会变更。因而咱们能够应用内容散列作为验证器,记录内容散列的字段是ETag。
而另一种比较简单粗犷的形式则是断定文件的最初一次批改工夫。如果文件的最初一次批改工夫变更了,咱们认为文件变更了。反之,则认为没有变更。记录文件最初一次变更工夫的字段是Last-Modified。

强验证器与弱验证器: 咱们将验证器分为两种:强验证器与弱验证器。弱验证器是易于生成,但对验证来熟存在许多限度甚至缺点。强验证器是比拟的现实抉择,但可能十分艰难(并且有时是不可能的)以高效地生成。Last-Modified是显式弱验证器除非能证实是强选择器。而ETag默认为强验证器,但咱们能够显示的将其指为弱验证器。

当然了相比于内容散列,应用最初一次批改工夫会有一些缺点,所以通常作为候补计划来应用。上面咱们将具体介绍这两种验证器:

Last-Modified:其中蕴含源头服务器认定的资源做出批改的日期及工夫。 它通常被用作一个验证器来判断接管到的或者存储的资源是否彼此统一。因为精确度比 ETag 要低,所以这是一个备用机制。
这里咱们给出一个示例:

Last-Modified: Tue, 15 Nov 1994 12:45:26 GMT

对应条件申请机制:申请能够在申请首部If-Modified-Since中携带上须要验证的响应用于响应验证。服务器只在所申请的资源在给定的日期工夫之后对内容进行过批改的状况下才会将资源返回,状态码为200 。如果申请的资源从那时起未经批改,那么返回一个不带有音讯主体的304响应。

上面咱们做一个总结:

  • Last-Modified/If-Modified-Since用于资源验证。如果资源未变更,响应中不会发返回音讯主体。
  • 其验证优先级将低于上面要讲到的ETag。因而验证时,如果存在If-None-Match,则If-Modified-Since会被疏忽
  • Last-Modified值也能够被If-Unmodified-SinceIf-Range字段携带以示意条件抉择。在这种状况下,只有当资源在指定的工夫之后没有进行过批改的状况下,服务器才会返回申请的资源。如果所申请的资源在指定的工夫之后产生了批改,那么会返回412谬误。须要留神这是条件申请机制而非验证机制。此处提及,是防止与If-Modified-Since。因为看到有些文章中感觉这两个字段都用于缓存校验,这种说法是不正确的。

ETag:ETag响应头是资源的特定版本的标识符。其用法如下:

  • ETag实体标签是不通明的验证器,用以辨别雷同的多个示意资源,而不论资源状态是否随工夫变动。
  • 能够通过增加W/将Etag指为弱验证器。例如以下示意中,不带w/的默认应用强验证器,而w/则显示表明应用弱验证器

    ETag: W/""
    ETag: ""
  • ETag/If-None-Match被用于进行缓存校验。ETag 属性之间的比拟采纳的是弱比拟算法,即两个文件除了每个比特都雷同外,内容统一也能够认为是雷同的。例如,如果两个页面仅仅在页脚的生成工夫有所不同,就能够认为二者是雷同的。
  • If-Match:示意这是一个条件申请。如果资源匹配才返回,不匹配返回416.须要留神这是条件申请机制而非验证机制。这里提出只是辨别上文的If-None-Match。防止混同。这种机制个别用于解决地面碰撞问题而非缓存验证

地面碰撞: 设想有这样一种场景。你正在编辑一个文档,文档当初的版本是v1.0。因而你目前的变更时基于v1.0的。但等你提交的时候,因为小明比你先提交,所以服务器的版本曾经变成小明提交的v1.1。如果你胜利提交,则小明编辑的内容就会隐没。这种状况称为地面碰撞。为了检测到这种状况,浏览器会提交If-Match或者If-Unmodified-Since进行条件申请,如果条件合乎,则能够胜利提交,否则返回412前提条件失败。如果对此感兴趣,可参阅:https://www.w3.org/1999/04/Editing/


整体梳理

为了不便了解,放了一张图来简述上文介绍的缓存过程:

还记得海绵宝宝.jpg那里咱们提出的问题吗?通过上述章节的介绍咱们能够来试试答复了。当然你也能够不往下翻而是回去看看那些问题,并帮忙浏览器解决问题。

  1. 服务器如何告知图片资源海绵宝宝.jpg的有效期?
  2. 浏览器如何计算图片是否过期(要晓得这图片是服务器转交给浏览器的)
  3. 服务器如何依据信息得悉浏览器的资源是不是无效的(毕竟服务器不止和一个浏览器对话,无奈记忆只能计算)
  4. 如果某次,服务器没有告知海绵宝宝.jpg这张图片资源的过期信息,浏览器还会存储资源吗
  5. 浏览器的缓存中可能有很多张海绵宝宝.jpg资源吗,如果有会怎么抉择呢
  6. 浏览器会如何缓存海绵宝宝.jpg(要晓得浏览器要解决很多申请,除了海绵宝宝.jpg,可能还有派大星.jpg,他们须要被辨别)

上面咱们来揭晓答案:
1、通过过期机制。就缓存时长而言,通常是max-age指令与Expires首部字段
具体内容能够参阅过期机制章节。
2、通过比对freshness lifetiime与age来断定。
3、通过验证机制。具体内容能够参阅验证机制章节。
4、这是一个不确定的答案,或者咱们要看浏览器自身的志愿。通常不会,不过浏览器本身能够采纳启发式过期周期计算。
5、这道题在上文中并没有提到,所以咱们仿佛还不能做出解答
6、同样,这也是咱们目前理解到的内容无奈解决的问题。

那么咱们须要持续深刻一些细节,以帮忙浏览器解决所有的问题。

  • 缓存如何在浏览器内进行存储
    如果要标示缓存资源那么最间接的形式就是以url以及申请办法作为主键进行存储。实际上RFC的标准也的确如此。然而鉴于,实际上申请办法往往被限度为get,因而能够只应用url作为主键。对于浏览器具体实现能够参阅:https://www.chromium.org/developers/design-documents/network-stack/disk-cache
  • 是否可能同一资源对应多条缓存
    如果申请指标受内容协商影响,则其缓存记录可能蕴含多个响应存储内容,每个存储响应由原始申请抉择题目字段的值作为辅助密钥来进行辨别。用Vary首部字段来实现。当缓存收到了一个能够被带有Vary首部字段的存储,除非能够满足Vary字段中所有抉择的首部字段,否则不该当应用该响应。
    而如果有多条缓存都能够满足条件,缓存将须要抉择其中的一个进行应用。如果存在一个抉择首部字段领有一种已知机制能够进行择优(例如,Accept中的qvalues值,以及类似的申请首部字段),那么该机制就可能用作抉择更优的响应。如果没有这样的机制,将会通过Date首部字段依据最近日期抉择一个最近期的响应。

到了这里,咱们的旅程就完结了。期间,咱们帮忙浏览器实现了他对于海绵宝宝.jpg的缓存使命。置信这将是一次难忘的旅程。:)

在后文中将附上一些容易呈现的误会和在这个过程中参阅的材料。如果对于这趟旅程的细节你还想理解更多,无妨持续浏览上来!


易混同内容

上面来看看对于缓存容易混同的点:

强缓存与弱缓存概念:
缓存概念并不辨别强弱。是缓存验证机制中的验证器分为强验证器与弱验证器。
可参阅RFC7232第2.1节

强制缓存与协商缓存:
从便于了解的角度来讲没有问题,但这不是标准中的概念。实际上IETF中对于HTTP的Cache标准次要从过期机制与验证机制来形容缓存。可参阅RFC7234全文

有了ETag就不须要Last-Modified:
事实上,这两种都应该存在。因为你不能保障门路上都是HTTP1.1协定。对于不能了解ETag的协定来说,缓存将生效。而如果都有,那对于能够了解ETag的则会疏忽last-Modified,因而有益无害。Cache-Control与Expires同理。可参阅RFC7232第2.4节

memory cache和disk cache是http缓存的两个地位
认真看network就会发现size那一栏有时会呈现disk cache有时候会呈现memory cache。所以http缓存会依据肯定规定决定存进内存还是硬存?
并不是这样,memory cache和http cache是并列的缓存类型,没有蕴含关系。http cache作为长久化存储肯定会进入disk的,所以disk cache和http cache是一种存储形式。
要证实memory cache不是http cache的一部分是很简略的。因为开发者能够在开发中工具的network里禁用缓存。首先咱们间接加载一次申请

能够看到资源有的从memory cache加载,有的从disk cache加载。当初关上禁用缓存。

当显示的禁用缓存后,从disk加载的曾经间接申请了。memory cache的仍然从memory cache去读取。可见资源的可缓存性不影响memory cache的行为。
在后面的讲述中咱们曾经晓得memory cache优先级大于disk cache。设若一个资源是不可长期缓存的,例如设置了no-store,然而并不会影响其内存是否缓存的行为。反之如果memory cache的资源如果被设定为可存储他最终肯定也是会进入硬存长久化存储的。
咱们思考一个内容有什么用很难,咱们反向思考一下没有memory cache会产生什么。咱们加载了一张图用做头像框。整个页面有10个头像要加载。如果这张图被服务器标不能够缓存,浏览器真的不缓存他就要把同一张图加载10遍。这正当吗?这不合理,所以memory cache不属于http缓存的一种模式,不受协定影响,是一种短效快捷存储。
mozilla提供了对于内存缓存敞开的选项。其中对默认缓存内容进行了形容。其默认是开启的。可参见mozilla的memory cache配置。不同浏览器实现可能存在差别。


附录

对于缓存须要理解的首部字段

字段名称 参考文档 字段类型 字段形容
Age https://developer.mozilla.org… 响应首部 Age 音讯头里蕴含对象在缓存代理中存贮的时长,以秒为单位。.
Pragma https://developer.mozilla.org… 通用首部 它用来向后兼容只反对 HTTP/1.0 协定的缓存服务器
Date https://developer.mozilla.org… 通用首部 蕴含了报文创立的日期和工夫。
Vary https://developer.mozilla.org… 响应首部 它被服务器用来表明在 内容协商算法中抉择一个资源代表的时候应该应用哪些头部信息
Last-Modified https://developer.mozilla.org… 响应首部 蕴含源头服务器认定的资源做出批改的日期及工夫。
If-Modified-Since https://developer.mozilla.org… 申请首部 服务器只在所申请的资源在给定的日期工夫之后对内容进行过批改的状况下才会将资源返回。
If-Unmodified-Since https://developer.mozilla.org… 申请首部 如果所申请的资源在指定的工夫之后产生了批改,那么会返回 412 (Precondition Failed) 谬误。
ETag https://developer.mozilla.org… 申请首部 ETagHTTP响应头是资源的特定版本的标识符。
If-Match https://developer.mozilla.org… 申请首部 服务器仅在申请的资源满足此首部列出的 ETag值时才会返回资源
If-None-Match https://developer.mozilla.org… 申请首部 当且仅当服务器上没有任何资源的 ETag 属性值与这个首部中列出的相匹配的时候,服务器端会才返回所申请的资源
If-Range https://developer.mozilla.org… 申请首部 If-Range字段用来使得Range头字段在肯定条件下起作用:当字段值中的条件失去满足时,Range 头字段才会起作用,同时服务器回复206 局部内容状态码
Expires https://developer.mozilla.org… 实体首部 Expires 响应头蕴含日期/工夫, 即在此时候之后,响应过期。
cache-control https://developer.mozilla.org… 通用首部 用于在http申请和响应中,通过指定指令来实现缓存机制

参考文档

  • preload:https://developer.mozilla.org…
  • server push:https://blog.csdn.net/wetest_…
  • https://jakearchibald.com/201…
  • push cache:https://www.cnblogs.com/xgqfr…
  • webkit页面缓存:https://webkit.org/blog/427/w…
  • chromium硬盘存储:https://www.chromium.org/deve…
  • http缓存:https://www.chromium.org/deve…
  • 内存缓存:http://kb.mozillazine.org/Bro…
  • http://kb.mozillazine.org/Bro…
  • chromium:https://www.chromium.org/deve…
  • web worker:https://www.chromium.org/blin…
  • http://www.whatwg.org/specs/w…
  • https://docs.google.com/docum…
  • blink worker:https://docs.google.com/docum…
  • 过程间通信:https://www.chromium.org/deve…
  • 多过程资源加载:https://www.chromium.org/deve…
  • chromium如何显示网页面:https://www.chromium.org/deve…
  • 资源申请:https://chromium.googlesource…
  • gpu程序缓存:https://docs.google.com/docum…
  • 渲染:https://docs.google.com/docum…
  • 重绘原理:https://docs.google.com/docum…
  • https://ci.chromium.org/p/chr…
  • 视觉格式化模型:https://www.w3.org/TR/CSS21/v…
  • 浏览器:http://taligarsiel.com/Projec…
  • html:https://whatwg-cn.github.io/h…
  • webcore渲染 https://webkit.org/blog/114/
  • http rfc https://www.ietf.org/rfc/rfc2…
  • ietf rfc查问 https://www.rfc-editor.org/se…
  • url 解析https://webkit.org/blog/7086/…
  • server worker: https://webkit.org/blog/8090/…
  • webworker缓存:https://w3c.github.io/Service…
  • server push标准:https://www.rfc-editor.org/rf…
  • https://www.rfc-editor.org/rf…
  • url加载:https://developer.chrome.com/…
  • chrome 缓存:https://developer.chrome.com/…
  • loader:https://calendar.perfplanet.c…
  • http缓存:https://www.w3.org/Protocols/…
  • 缓存协定:https://www.rfc-editor.org/rf… https://www.rfc-editor.org/rf…
  • http1.1 https://www.w3.org/Protocols/… (已被7230~7237取代)
  • http1.0:https://www.ietf.org/rfc/rfc1…
  • http:https://www.rfc-editor.org/se…
  • 文档变更检测(地面碰撞):https://www.w3.org/1999/04/Ed…

推荐阅读
  • 本文介绍了Windows操作系统的版本及其特点,包括Windows 7系统的6个版本:Starter、Home Basic、Home Premium、Professional、Enterprise、Ultimate。Windows操作系统是微软公司研发的一套操作系统,具有人机操作性优异、支持的应用软件较多、对硬件支持良好等优点。Windows 7 Starter是功能最少的版本,缺乏Aero特效功能,没有64位支持,最初设计不能同时运行三个以上应用程序。 ... [详细]
  • 如何查询zone下的表的信息
    本文介绍了如何通过TcaplusDB知识库查询zone下的表的信息。包括请求地址、GET请求参数说明、返回参数说明等内容。通过curl方法发起请求,并提供了请求示例。 ... [详细]
  • Monkey《大话移动——Android与iOS应用测试指南》的预购信息发布啦!
    Monkey《大话移动——Android与iOS应用测试指南》的预购信息已经发布,可以在京东和当当网进行预购。感谢几位大牛给出的书评,并呼吁大家的支持。明天京东的链接也将发布。 ... [详细]
  • 本文分享了一个关于在C#中使用异步代码的问题,作者在控制台中运行时代码正常工作,但在Windows窗体中却无法正常工作。作者尝试搜索局域网上的主机,但在窗体中计数器没有减少。文章提供了相关的代码和解决思路。 ... [详细]
  • 如何使用Java获取服务器硬件信息和磁盘负载率
    本文介绍了使用Java编程语言获取服务器硬件信息和磁盘负载率的方法。首先在远程服务器上搭建一个支持服务端语言的HTTP服务,并获取服务器的磁盘信息,并将结果输出。然后在本地使用JS编写一个AJAX脚本,远程请求服务端的程序,得到结果并展示给用户。其中还介绍了如何提取硬盘序列号的方法。 ... [详细]
  • Metasploit攻击渗透实践
    本文介绍了Metasploit攻击渗透实践的内容和要求,包括主动攻击、针对浏览器和客户端的攻击,以及成功应用辅助模块的实践过程。其中涉及使用Hydra在不知道密码的情况下攻击metsploit2靶机获取密码,以及攻击浏览器中的tomcat服务的具体步骤。同时还讲解了爆破密码的方法和设置攻击目标主机的相关参数。 ... [详细]
  • Python开源库和第三方包的常用框架及库
    本文介绍了Python开源库和第三方包中常用的框架和库,包括Django、CubicWeb等。同时还整理了GitHub中最受欢迎的15个Python开源框架,涵盖了事件I/O、OLAP、Web开发、高性能网络通信、测试和爬虫等领域。 ... [详细]
  • 本文总结了初学者在使用dubbo设计架构过程中遇到的问题,并提供了相应的解决方法。问题包括传输字节流限制、分布式事务、序列化、多点部署、zk端口冲突、服务失败请求3次机制以及启动时检查。通过解决这些问题,初学者能够更好地理解和应用dubbo设计架构。 ... [详细]
  • 通过Anaconda安装tensorflow,并安装运行spyder编译器的完整教程
    本文提供了一个完整的教程,介绍了如何通过Anaconda安装tensorflow,并安装运行spyder编译器。文章详细介绍了安装Anaconda、创建tensorflow环境、安装GPU版本tensorflow、安装和运行Spyder编译器以及安装OpenCV等步骤。该教程适用于Windows 8操作系统,并提供了相关的网址供参考。通过本教程,读者可以轻松地安装和配置tensorflow环境,以及运行spyder编译器进行开发。 ... [详细]
  • 微软头条实习生分享深度学习自学指南
    本文介绍了一位微软头条实习生自学深度学习的经验分享,包括学习资源推荐、重要基础知识的学习要点等。作者强调了学好Python和数学基础的重要性,并提供了一些建议。 ... [详细]
  • 基于PgpoolII的PostgreSQL集群安装与配置教程
    本文介绍了基于PgpoolII的PostgreSQL集群的安装与配置教程。Pgpool-II是一个位于PostgreSQL服务器和PostgreSQL数据库客户端之间的中间件,提供了连接池、复制、负载均衡、缓存、看门狗、限制链接等功能,可以用于搭建高可用的PostgreSQL集群。文章详细介绍了通过yum安装Pgpool-II的步骤,并提供了相关的官方参考地址。 ... [详细]
  • Windows下配置PHP5.6的方法及注意事项
    本文介绍了在Windows系统下配置PHP5.6的步骤及注意事项,包括下载PHP5.6、解压并配置IIS、添加模块映射、测试等。同时提供了一些常见问题的解决方法,如下载缺失的msvcr110.dll文件等。通过本文的指导,读者可以轻松地在Windows系统下配置PHP5.6,并解决一些常见的配置问题。 ... [详细]
  • centos安装Mysql的方法及步骤详解
    本文介绍了centos安装Mysql的两种方式:rpm方式和绿色方式安装,详细介绍了安装所需的软件包以及安装过程中的注意事项,包括检查是否安装成功的方法。通过本文,读者可以了解到在centos系统上如何正确安装Mysql。 ... [详细]
  • Sleuth+zipkin链路追踪SpringCloud微服务的解决方案
    在庞大的微服务群中,随着业务扩展,微服务个数增多,系统调用链路复杂化。Sleuth+zipkin是解决SpringCloud微服务定位和追踪的方案。通过TraceId将不同服务调用的日志串联起来,实现请求链路跟踪。通过Feign调用和Request传递TraceId,将整个调用链路的服务日志归组合并,提供定位和追踪的功能。 ... [详细]
  • ejava,刘聪dejava
    本文目录一览:1、什么是Java?2、java ... [详细]
author-avatar
SaraCody_174
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有