HTTP缓存主要用在对一些实时性要求不高的静态文件进行的缓存,每每都是存在浏览器端,防止这些“多余”的请求重复的访问服务器,对服务器形成压力,从而提升网站的性能。css
现有两端,浏览器C和服务器端S。浏览器
浏览器向服务器发送请求,获取一个文件f缓存
服务器就把f给返回浏览器服务器
假如这个文件的内容变化不是那么快,一两周更新一次,浏览器每次请求服务器都返回相同的文件,岂不是对服务器资源的一种浪费?微信
如何解决呢?性能
浏览器把请求后拿到的文件存到本地,等下次请求的时候,看看本地是否有缓存文件,若是有,直接拿本地的文件,岂不是就不用请求服务器了?这其实就是http缓存的最最根本的原理。优化
C端浏览器端把请求来的文件缓存到如图下f的小方格内 网站
等到下次C端再次请求此文件时,就直接从浏览器缓存的文件中拿,而再也不向S服务器端发起请求了3d
如下浏览器截图中标红的部分,就是没有发起请求,直接从浏览器缓存中获取的数据代理
浏览器端有了缓存以后,不能一直有效吧,若是文件更新了,咱们还继续使用浏览器缓存中的数据,虽然说时效性不强,但长期使用旧文件也不算合理吧。
http协议提供了两种维度来让缓存失效:时间和文件的修改。
时间维度很简单,就是设定一个缓存时间段,过了这个时间段,缓存就自动失效了,浏览器就会发起请求获取文件。这个设定时间的http字段就是cache-control
字段。
cache-control
可设置的字段值有:
cache-control 缓存原理
第一次访问请求,客户端C向服务端S发起一个文件请求,服务器返回文件并在response
中加了响应头"Cache-Control:max-age=60",这样一来,这个f文件只能在浏览器端存 60秒
在这60秒钟,客户端请求服务器的f文件会直接从缓存中拿取
60秒事后,缓存失效,浏览器再次请求文件须要从新向服务器发起请求。
注意:假如说请求中包含“Cache-Control:max-age=0”或者“Cache-Control:no-store”不管响应中返回的"max-age"值是多少,都不会缓存到服务器。浏览器中对于地址栏中直接输入文件地址的请求作了优化处理,加上了“Cache-Control:max-age=0”,也就是说,若是这个css、js或者其余静态文件是经过你在浏览器上直接输入得到的,将会每时每刻都是获取最新的。
这种维度比较的科学:浏览器先请求服务得到文件后,服务器会返回该文件的最后修改时间Last-Modified
,做为文件的一个标识,下次浏览器请求的时候,会带着这个标识去请求(此时为If-Modified-Since
),而后服务器作校验,若是说时间标识If-Modified-Since
等于服务器的文件修改时间,则说明没有修改,返回304状态码,浏览器从缓存中获取文件,可是若是浏览器保存的时间标识If-Modified-Since
小于服务器端的文件修改时间,那么,说明文件发生了修改,浏览器就会从新获取新的文件。 (If-Modified-Since
的时间若是大于服务器端文件的时间,会被认为是错误的请求)
如图,浏览器C向服务器发S起请求,服务器S返回文件的同时还会返回文件的最后修改时间Last-Modified
做为文件时间标识,浏览器会将文件和文件时间标识都缓存起来。
假如服务器端的文件f并无被修改,服务器经过判断请求头带的时间标识If-Modified-Since
得出结论后,都会返回状态码304
告诉浏览器文件没有被修改,让浏览器使用缓存。
假如服务器端的文件f修改了,那么,浏览器将从新获取文件,并缓存到浏览器中。
虽然经过文件最后修改时间做为标识已经很完美了,可是,仍是可能存在一个问题:就是有可能服务器端的文件修改后,又改回原来的样子,这样,虽然文件最后修改时间变了,可是,文件内容并无改变。这样仍是会有多余的请求到达服务器,该如何处理呢? 能够将文件内容做为一个惟一标识,例如能够对文件内容取MD5值做为字段(etag
)也传给浏览器端,假如这个文件内容没变化,那么MD5值也不会改变。那么,处理流程就变成了这样:服务器端先判断文件修改时间是否发生了变化,若是发生了变化,那么再对比浏览器传来的If-None-Match
即浏览器端保留的E-tag
值,若是发生了变化,则证实文件修改了,须要浏览器从新下载文件,若是没有,则证实文件内容没变化,返回304状态码。
如图,浏览器C要访问服务器S的f文件,服务器S返回了文件最后修改时间Last-Modified
和文件的内容标识E-tag
,浏览器将这两个字段及其文件缓存了起来
当文件最后修改时间没变,文件内容也没变的时候,返回304,让浏览器从缓存中拿取文件。
当文件最后修改时间变了,文件内容没变的时候,返回304,让浏览器从缓存中拿取文件。
当文件修改时间变了,文件内容也变了的时候,服务器会从新下发新的文件给浏览器。
此维度让缓存失效牵扯的http字段有点多,咱们最后整理一下: 文件最后修改时间字段:
Last-Modified
If-Modified-Since
文件内容标识字段:
E-tag
If-None-Match
互联网技术窝
或者加微信共同探讨交流: