俄罗斯贵宾会-俄罗斯贵宾会官网
做最好的网站

浏览器缓存控制俄罗斯贵宾会,浏览器缓存

HTTP 缓存

2016/11/01 · 基础技术 · HTTP, 缓存

原文出处: 凹凸实验室   

俄罗斯贵宾会 1

有时,HTTP 中的缓存可能会非常让人头疼。
按照文档正确地使用 HTTP 并不是那么困难,但事实上,不同的浏览器和 HTTP 版本常常困扰着我们。

通过 Stack Overflow 的搜索结果,你可以很轻易地发现很多人有相同的困扰。我们自己或是不必或是没有时间去钻研所有的边缘的情况。

所以这里有一些博主总结的实用并速记的规则,并且在未来博主也会持续地跟进和更新。

浏览器缓存控制,浏览器缓存

浏览器缓存控制

Last-Modified/ If-Modified-Since

在浏览器第一次请求某一个URL时,服务器端的返回状态码200,内容是客户端请求的资源,同时有一个Last-Modified的属性标记此文件在服务器端最后被修改的时间。

Last-Modified格式类似这样:Last-Modified : Fri , 12 May 2006 18:53:33 GMT

客户端第二次请求此URL时,根据HTTP协议的规定,浏览器会向服务器传送If-Modified-Since报头,询问该时间之后文件是否有被修改过:

If-Modified-Since : Fri , 12 May 2006 18:53:33 GMT

如果服务器端的资源没有变化,则自动返回 HTTP 304(Not Changed.)状态码,内容为空,这样就节省了传输数据量。当服务器端代码发生改变或者重启服务器时,则重新发出资源,返回和第一次请求类似。从而保证不向客户端重复发出资源,也保证当服务器有变化时,客户端能够得到最新的资源。

Last-Modified的问题

1、一些文件会被编辑,但内容并未改变,这个时候不希望客户端认为这个文件被修改了,而重新获取资源。

2、某些文件修改非常频繁,比如在秒以下的时间内进行修改,If-Modified-Since无法检查到。

3、某些服务器不能精确的得到文件的最后修改时间。

 

Expires

Expires用来控制缓存失效的日期。当浏览器看到响应中有一个Expires头时,它会和相应的组件一起保存到其缓存中,只要组件没有过期,浏览器就会使用缓存版本而不会进行任何的HTTP请求。长久的Expires头适用于图片等不经常更新的资源。Expires设置的日期格式必须为GMT(格林尼治标准时间)。

Expires:Wed, 11 Jan 2017 08:10:26 GMT

Expires的不足:

首先,Expires头使用的是一个特定的时间,要求客户端和服务器端的时钟严格同步。如果服务器和客户端的时间不统一,这有可能出现缓存提前失效的情况,存在不稳定性。其次,假如Expires的日期到来,需要在服务器配置中再提供一个新的日期。

 

Cache-Control

HTTP1.1引入了Cache-Control头来克服Expires头的不足。Cache-Control使用max-age制定组件被缓存多久,以秒为单位。例如

Cache-Control:max-age=3600表示组件将被缓存60分钟。

如果max-age和Expires同时出现,则max-age有更高的优先级,浏览器会根据max-age的时间来确认缓存过期时间。

常用 cache-directive 值

Cache-directive

说明

public

所有内容都将被缓存(客户端和代理服务器都可缓存)

private

内容只缓存到私有缓存中(仅客户端可以缓存,代理服务器不可缓存),默认值

no-cache

必须先与服务器确认返回的响应是否被更改,然后才能使用该响应来满足后续对同一个网址的请求。因此,如果存在合适的验证令牌 (ETag),no-cache 会发起往返通信来验证缓存的响应,如果资源未被更改,可以避免下载。

no-store

所有内容都不会被缓存到缓存或 Internet 临时文件中

must-revalidation/proxy-revalidation

如果缓存的内容失效,请求必须发送到服务器/代理以进行重新验证

max-age=xxx (xxx is numeric)

缓存的内容将在 xxx 秒后失效, 这个选项只在HTTP 1.1可用。如果和Last-Modified一起使用时, 优先级较高

 

浏览器的不同操作

打开新窗口

如果指定cache-control的值为private、no-cache、must-revalidate,那么打开新窗口访问时都会重新访问服务器。而如果指定了max-age值,那么在此值内的时间里就不会重新访问服务器,例如:Cache-control: max-age=5 表示当访问此网页后的5秒内不会去再次访问服务器.

在地址栏回车

如果值为private或must-revalidate,则只有第一次访问时会访问服务器,以后就不再访问。如果值为no-cache,那么每次都会访问。如果值为max-age,则在过期之前不会重复访问。

按后退按扭

如果值为private、must-revalidate、max-age,则不会重访问,而如果为no-cache,则每次都重复访问.

按刷新按扭

无论为何值,都会重复访问.

 

Etag(Entity Tag)

服务器在检测缓存的组件是否和原始服务器上的组件匹配时有两种方法:

(1)比较最近修改日期;Last-Modified/If-Modified-since

(1)比较实体标签;Etag/If-None-Match(优先级比If-Modified-since高)

实体标签,是web服务器和浏览器用于确认缓存组件的有效性的一种机制。

           ETag:"50b1c1d4f775c61:df3"

第一次请求时:

1.客户端发起HTTP GET 请求一个资源;

2.服务器处理请求,返回资源,包括Http Etag和状态码200

第二次请求时:

1.客户端发起 HTTP GET 请求一个文件,请求中包括一个If-None-Match头,内容就是第一次请求时服务器返回的Etag的值

2.服务器判断接受到的Etag和计算出来的Etag是否匹配。若匹配,返回304状态码,客户端继续使用本地的缓存。若不匹配,返回资源和新的ETag。

ETag带来的问题

ETag通常使用组件的某些属性来构造它,这些属性对于特定的寄宿了网站服务器来说是唯一的。当浏览器从一台服务器上获取了原始组件,之后又向另外一台不同的服务器发起条件GET请求时,ETag是不会匹配的。

对组件进行不必要的重新加载还会影响服务器的性能并增加带宽开销。如果你的RoundRobin Rotation集群中有n台服务器,下一次用户缓存中的Etag能和服务器匹配的概率是1/n。Etag还会降低代理缓存的效率,因为代理的与自身的不匹配会重新下载。

HTTP响应优化

移除ETag,Expires,使用Cache-Control控制本地缓存。

http://www.bkjia.com/Javascript/1195099.htmlwww.bkjia.comtruehttp://www.bkjia.com/Javascript/1195099.htmlTechArticle浏览器缓存控制,浏览器缓存 浏览器缓存控制 Last-Modified/ If-Modified-Since 在浏览器第一次请求某一个URL时,服务器端的返回状态码200,内容...

静态资源

永远不会修改的内容:JS 和 CSS 文件,图片,和任何类型的二进制文件都属于这个类目。

永远,我确实说的是永远。为静态资源指定版本号是很通用的做法。它们无论什么时候改动了,它们的 URL 就改变了。

这里是一些针对静态资源的简单的规则:

  • 在文件或者路径中嵌入指纹。避免为指纹使用查询字符串。另外,确保生成的URL长度超过8个不同的字符。
  • 使用这些 HTTP 头:
Cache-Control: public, max-age=31536000 Expires: (一年后的今天)
ETag: (基于内容生成) Last-Modified: (过去某个时间) Vary:
Accept-Encoding

<table>
<colgroup>
<col style="width: 50%" />
<col style="width: 50%" />
</colgroup>
<tbody>
<tr class="odd">
<td><div class="crayon-nums-content" style="font-size: 13px !important; line-height: 15px !important;">
<div class="crayon-num" data-line="crayon-5b8f6a212f047787520650-1">
1
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6a212f047787520650-2">
2
</div>
<div class="crayon-num" data-line="crayon-5b8f6a212f047787520650-3">
3
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6a212f047787520650-4">
4
</div>
<div class="crayon-num" data-line="crayon-5b8f6a212f047787520650-5">
5
</div>
</div></td>
<td><div class="crayon-pre" style="font-size: 13px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;">
<div id="crayon-5b8f6a212f047787520650-1" class="crayon-line">
Cache-Control: public, max-age=31536000
</div>
<div id="crayon-5b8f6a212f047787520650-2" class="crayon-line crayon-striped-line">
Expires: (一年后的今天)
</div>
<div id="crayon-5b8f6a212f047787520650-3" class="crayon-line">
ETag: (基于内容生成)
</div>
<div id="crayon-5b8f6a212f047787520650-4" class="crayon-line crayon-striped-line">
Last-Modified: (过去某个时间)
</div>
<div id="crayon-5b8f6a212f047787520650-5" class="crayon-line">
Vary: Accept-Encoding
</div>
</div></td>
</tr>
</tbody>
</table>

针对静态资源的设置就是那么简单。

动态资源

针对应用程序私密性和新鲜度方面需求的不同,我们应该使用不同的缓存控制设置。

对于非私密性和经常性变动的资源(想像一下股票信息),我们应该使用下面这些:

Cache-Control: public, max-age=0 Expires: (当前时间) ETag: (基于内容生成) Last-Modified: (过去某个时间) Vary: Accept-Encoding

1
2
3
4
5
Cache-Control: public, max-age=0
Expires: (当前时间)
ETag: (基于内容生成)
Last-Modified: (过去某个时间)
Vary: Accept-Encoding

这些设置的效果是:这些资源可以被公开地(通过浏览器和代理服务器)缓存起来。每一次在浏览器使用这些资源之前,浏览器或者代理服务器会检查这些资源是否有更新的版本,如果有,就把它们下载下来。

这样的设置需要注意,浏览器在重新检查资源时效性方面有一定的灵活性。典型的是,当用户点击了「返回/前进」按钮时,浏览器不会重新检查这些资源文件,而是直接使用缓存的版本。你如果需要更严格的控制,需要告知浏览器即使当用户点击了「返回/前进」按钮,也需要重新检查这些资源文件,那么可以使用:

Cache-Control: public, no-cache, no-store

1
Cache-Control: public, no-cache, no-store

不是所有的动态资源都会马上变成过时的资源。如果它们可以保持至少5分钟的时效,可以使用:

Cache-Control: public, max-age=300

1
Cache-Control: public, max-age=300

经过这样的设置,浏览器只会在5分钟之后才重新检查。在这之前,缓存的内容会被直接使用。如果在5分钟后,这些过时的内容需要严格控制,你可以添加 must-revalidate 字段:

Cache-Control: public, max-age=300, must-revalidate

1
Cache-Control: public, max-age=300, must-revalidate

对于私密或者针对用户的内容,需要把 public 替换为 private 以避免内容被代理缓存。

Cache-Control: private, …

1
Cache-Control: private, …

Cache-Control 和 Expires

当同时使用 Cache-ControlExpires 时,Cache-Control 获得优先权。

同时使用 Cache-ControlExpires 意味着得到更广泛的支持(被不同的浏览器和版本)。当然,它们两个应该被配置成相同的时效值,以避免引起困惑。

参考 Expires: vs. Cache-Control: max-age

本文由俄罗斯贵宾会发布于Web前端,转载请注明出处:浏览器缓存控制俄罗斯贵宾会,浏览器缓存

您可能还会对下面的文章感兴趣: