关于nginx:Nginx下关于缓存控制字段cachecontrol的配置说明

0次阅读

共计 10883 个字符,预计需要花费 28 分钟才能阅读完成。

HTTP 协定的 Cache -Control 指定申请和响应遵循的缓存机制。在申请音讯或响应音讯中设置 Cache-Control 并不会影响另一个音讯处理过程中的缓存处理过程。
申请时的缓存指令 包含: no-cache、no-store、max-age、max-stale、min-fresh、only-if-cached 等。
响应音讯中的指令 包含: public、private、no-cache、no- store、no-transform、must-revalidate、proxy-revalidate、max-age。

Cache-Control:
设置绝对过期工夫, max-age 指明以秒为单位的缓存工夫. 若对动态资源只缓存一次, 能够设置 max-age 的值为 315360000000 (一万年). 比方对于提交的订单,为了避免浏览器回退从新提交,能够应用 Cache-Control 之 no-store 相对禁止缓存,即使浏览器回退仍然申请的是服务器,进而判断订单的状态给出相应的提示信息!

一.   浏览器中对于 Cache 的 3 属性:
1. Cache-Control:
设置绝对过期工夫, max-age 指明以秒为单位的缓存工夫. 若对动态资源只缓存一次, 能够设置 max-age 的值为 315360000000 (一万年). 比方对于提交的订单,为了避免浏览器回退从新提交,能够应用 Cache-Control 之 no-store 相对禁止缓存,即使浏览器回退仍然申请的是服务器,进而判断订单的状态给出相应的提示信息!

Http 协定的 cache-control 的常见取值及其组合释义:
no-cache: 数据内容不能被缓存, 每次申请都从新拜访服务器, 若有 max-age, 则缓存期间不拜访服务器.
no-store: 不仅不能缓存, 连暂存也不能够(即: 长期文件夹中不能暂存该资源).
private(默认): 只能在浏览器中缓存, 只有在第一次申请的时候才拜访服务器, 若有 max-age, 则缓存期间不拜访服务器.
public: 能够被任何缓存区缓存, 如: 浏览器、服务器、代理服务器等.
max-age: 绝对过期工夫, 即以秒为单位的缓存工夫.
no-cache, private: 关上新窗口时候从新拜访服务器, 若设置 max-age, 则缓存期间不拜访服务器.
–  private, 负数的 max-age: 后退时候不会拜访服务器.
–  no-cache, 负数的 max-age: 后退时会拜访服务器.

2. Expires:
设置以分钟为单位的相对过期工夫, 优先级比 Cache-Control 低, 同时设置 Expires 和 Cache-Control 则后者失效. 也就是说要留神一点:  Cache-Control 的优先级高于 Expires

expires 起到管制页面缓存的作用,合理配置 expires 能够缩小很多服务器的申请, expires 的配置能够在 http 段中或者 server 段中或者 location 段中.  比方管制图片等过期工夫为 30 天, 能够配置如下:
location ~ .(gif|jpg|jpeg|png|bmp|ico)$ {

root /var/www/img/`;`

expires 30d;

}
再比方:
location ~ .(wma|wmv|asf|mp3|mmf|zip|rar|swf|flv)$ {

root /var/www/upload/`;`

expires max;

}
3. Last-Modified:
该资源的最初批改工夫, 在浏览器下一次申请资源时, 浏览器将先发送一个申请到服务器上, 并附上 If-Unmodified-Since 头来阐明浏览器所缓存资源的最初批改工夫, 如果服务器发现没有批改, 则间接返回 304(Not Modified)回应信息给浏览器(内容很少), 如果服务器比照工夫发现批改了, 则照常返回所申请的资源. 

须要留神:
1) Last-Modified 属性通常和 Expires 或 Cache-Control 属性配合应用, 因为即便浏览器设置缓存, 当用户点击”刷新”按钮时, 浏览器会疏忽缓存持续向服务器发送申请, 这时 Last-Modified 将可能很好的减小回应开销.

2) ETag 将返回给浏览器一个资源 ID, 如果有了新版本则失常发送并附上新 ID, 否则返回 304,然而在服务器集群状况下, 每个服务器将返回不同的 ID, 因而不倡议应用 ETag.

以上形容的客户端浏览器缓存是指存储地位在客户端浏览器, 然而对客户端浏览器缓存的理论设置工作是在服务器上的资源中实现的. 尽管下面介绍了有对于客户端浏览器缓存的属性, 然而实际上对这些属性的设置工作都须要在服务器的资源中做设置. 通常有两种操作伎俩对浏览器缓存进行设置, 一个是通过页面指令申明来设置, 另外一个是通过编程形式来设置.

上面是相干页面设置 Cache-Control 头信息的几个简略配置:
例一:
if ($request_uri ~* "^/$|^/search/.+/|^/company/.+/"`) {`

add_header    Cache-Control  max-age=3600;

}
集体了解的 max-age 意思是:客户端本地的缓存,在配置的生存工夫内的,客户端能够间接应用,超出生存工夫的,到服务器上取新数据。当然这些还要看客户端浏览器的设置。

例二:
location ~ .*.(css|js|swf|php|htm|html)$ {

add_header Cache-Control no-store;

}
例三:
location ~ .*.(js|css)$ {

expires 10d;

}
例四: 将 html 结尾的申请加上 no-cache
location / {

access_log /data/nginx/log/xxx`.log api;`

root /home/www/html`;`

if ($request_filename ~ .*.(htm|html)$)

{

add_header Cache-Control no-cache;

}

}
二.   http Headers 模块 (设置 HTTP 报文的头标)
Nginx 的 ngx_http_headers_module 模块能够对 Cache-Control 头相干的货色进行配置, 比方:
expires     24h;

expires     0;

expires     -1;

expires     epoch;

add_header  Cache-Control  private;

指令
add_header add_header
expires expires

减少头标
语法:add_header name value
默认值:none
作用域:http, server, location
当 HTTP 应答状态码为 200、204、301、302 或 304 的时候,减少指定的 HTTP 头标。其中头标的值能够应用变量。

expires
语法:expires [time|epoch|max|off
默认值:expires off
作用域:http, server, location
应用本指令能够管制 HTTP 应答中的“Expires”和“Cache-Control”的头标,(起到管制页面缓存的作用)。

能够在 time 值中应用负数或正数。“Expires”头标的值将通过以后零碎工夫加上您设定的 time 值来取得。

epoch

指定“Expires”的值为 1 January, 1970, 00:00:01 GMT。

max

指定“Expires”的值为 31 December 2037 23:59:59 GMT,“Cache-Control”的值为 10 年。

指定“Expires”的值为 服务器以后工夫 -1s, 即永远过期.

“Cache-Control” 头标的值由您指定的工夫来决定:
    – 正数

Cache-Control: no-cache

   – 负数或零

Cache-Control: max-age = time

time 为您指定工夫的秒数。

“off” 示意不批改“Expires”和“Cache-Control”的值;

三.   Cache-Control
Cache-Control 通用音讯头字段被用于在 http 申请和响应中通过指定指令来实现缓存机制。缓存指令是单向的, 这意味着在申请设置的指令,在响应中不肯定蕴含雷同的指令。

响应头:Cache-Control:no-cache,强制每次申请间接发送给源服务器,而不通过本地缓存版本的校验。这对于须要确认认证利用很有用(能够和 public 联合应用),或者严格要求应用最新数据 的利用(不惜牺牲应用缓存的所有益处). 艰深解释:浏览器告诉服务器,本地没有缓存数据.

cache-control :
       max-age>0 时 间接从游览器缓存中提取;
       max-age<=0 时向 server 发送 http 申请确认 , 该资源是否有批改, 有的话 返回 200 , 无的话 返回 304。

艰深解释:响应头中的 Cache-Control:max-age=315360000 是告诉浏览器: 315360000 秒之内不要烦我, 就本人从缓冲区中刷新。

语法
指令不辨别大小写,并且具备可选参数,能够用令牌或者带引号的字符串语法。多个指令以逗号分隔。

指令
–   可缓存性
public
     表明响应能够被任何对象(包含:发送申请的客户端,代理服务器,等等)缓存。示意相应会被缓存,并且在多用户间共享。默认是 public。
private
     表明响应只能被单个用户缓存,不能作为共享缓存(即代理服务器不能缓存它), 能够缓存响应内容。响应只作为公有的缓存,不能在用户间共享。如果要求 HTTP 认证,响应会主动设置为 private。
no-cache
     在开释缓存正本之前,强制高速缓存将申请提交给原始服务器进行验证。指定不缓存响应,表明资源不进行缓存。然而设置了 no-cache 之后并不代表浏览器不缓存,而是在缓存前要向服务器确认资源是否被更改。因而有的时候只设置 no-cache 避免缓存还是不够保险,还能够加上 private 指令,将过期工夫设为过来的工夫。
only-if-cached
     表明客户端只承受已缓存的响应,并且不要向原始服务器查看是否有更新的拷贝.

–   到期
max-age=<seconds>
     设置缓存存储的最大周期,超过这个工夫缓存被认为过期(单位秒)。与 Expires 相同,工夫是绝对于申请的工夫。max-age 会笼罩掉 Expires。
s-maxage=<seconds>
     笼罩 max-age 或者 Expires 头,然而仅实用于共享缓存(比方各个代理),并且公有缓存中它被疏忽。也就是说 s -maxage 只用于共享缓存,比方 CDN 缓存(s -> share)。与 max-age 的区别是:max-age 用于一般缓存,而 s -maxage 用于代理缓存。如果存在 s -maxage, 则会笼罩 max-age 和 Expires.
max-stale[=<seconds>]
     表明客户端违心接管一个曾经过期的资源。可选的设置一个工夫(单位秒),示意响应不能超过的过期工夫。
min-fresh=<seconds>
     示意客户端心愿在指定的工夫内获取最新的响应。
stale-while-revalidate=<seconds>
     表明客户端违心承受古老的响应,同时在后盾异步查看新的响应。秒值批示客户违心承受古老响应的工夫长度。
stale-if-error=<seconds>
     示意如果新的查看失败,则客户违心承受古老的响应。秒数值示意客户在初始到期后违心承受古老响应的工夫。

–   从新验证和从新加载
must-revalidate
     缓存必须在应用之前验证旧资源的状态,并且不可应用过期资源。示意如果页面过期,则去服务器进行获取。
proxy-revalidate
     与 must-revalidate 作用雷同,但它仅实用于共享缓存(例如代理),并被公有缓存疏忽。
immutable
     示意响应注释不会随工夫而扭转。资源(如果未过期)在服务器上不产生扭转,因而客户端不应发送从新验证申请头(例如 If-None-Match 或 If-Modified-Since)来查看更新,即便用户显式地刷新页面。在 Firefox 中,immutable 只能被用在 https:// transactions.

–   其余
no-store
     缓存不应存储无关客户端申请或服务器响应的任何内容。示意相对禁止缓存!
no-transform
     不得对资源进行转换或转变。Content-Encoding, Content-Range, Content-Type 等 HTTP 头不能由代理批改。例如,非通明代理能够对图像格式进行转换,以便节俭缓存空间或者缩小迟缓链路上的流量。no-transform 指令不容许这样做。

两个小示例

  • 禁止缓存

发送如下指令能够敞开缓存。此外,能够参考 Expires 和 Pragma 题目。

Cache-Control: no-cache, no-store, must-revalidate

–  缓存动态资源节
对于应用程序中不会扭转的文件,通常能够在发送响应头前增加踊跃缓存。这包含例如由应用程序提供的动态文件,例如图像,CSS 文件和 JavaScript 文件。另请参阅 Expires 题目。

Cache-Control:public, max-age=31536000
这里扩大一下:
HTTP1.0
HTTP1.0 中通过 Pragma 管制页面缓存,通常设置的值为 no- cache,不过这个值不这么保险,通常还加上 Expires 置为 0 来达到目标。然而如咱们刻意须要浏览器或缓存服务器缓存住咱们的页面这个值则要设置为 Pragma。

HTTP1.1
HTTP1.1 中启用 Cache-Control 来管制页面的缓存与否,Cache-Control 是 http1.1 中的规范,能够看成是 expires 的补充, 应用的是绝对工夫的概念。留神几个罕用的参数:
no-cache:  浏览器和缓存服务器都不应该缓存页面信息;
public:  浏览器和缓存服务器都能够缓存页面信息;
no-store:  申请和响应的信息都不应该被存储在对方的磁盘零碎中;
must-revalidate:  对于客户机的每次申请,代理服务器必须想服务器验证缓存是否过期

目前 Cache-Control 申请字段被各个浏览器反对的较好,其优先级也比拟高,当和别的字段(如 Expires)一起用时,会笼罩其余字段。
四. nginx 配置管理浏览器动态缓存策略
浏览器缓存: expirescache-controllast-modifiedetag.   先来看一张图:


每个状态的具体阐明如下:
1、Last-Modified
在浏览器第一次申请某一个 URL 时,服务器端的返回状态会是 200,内容是你申请的资源,同时有一个 Last-Modified 的属性标记 (HttpReponse Header) 此文件在服务期端最初被批改的工夫,格局相似这样:

Last-Modified:Tue, 24 Feb 2019 08:01:04 GMT

客户端第二次申请此 URL 时,依据 HTTP 协定的规定,浏览器会向服务器传送 If-Modified-Since 报头(HttpRequest Header),询问该工夫之后文件是否有被批改过:

If-Modified-Since:Tue, 24 Feb 2019 08:01:04 GMT

如果服务器端的资源没有变动,则主动返回 HTTP304(NotChanged.)状态码,内容为空,这样就节俭了传输数据量。当服务器端代码产生扭转或者重启服务器时,则从新收回资源,返回和第一次申请时相似。从而保障不向客户端反复收回资源,也保障当服务器有变动时,客户端可能失去最新的资源。

留神: 如果 If-Modified-Since 的工夫比服务器以后工夫 (以后的申请工夫 request_time) 还晚,会认为是个非法申请

2、Etag 工作原理
HTTP 协定规格阐明定义 ETag 为“被申请变量的实体标记”(参见 14.19)。简略点即服务器响应时给申请 URL 标记,并在 HTTP 响应头中将其传送到客户端,相似服务器端返回的格局:

Etag:“5d8c72a5edda8d6a:3239″

客户端的查问更新格局是这样的:

If-None-Match:“5d8c72a5edda8d6a:3239″

如果 ETag 没扭转,则返回状态 304。即: 在客户端发出请求后,HttpReponse Header 中蕴含 Etag:“5d8c72a5edda8d6a:3239″
标识,等于通知 Client 端,你拿到的这个的资源有示意 ID:5d8c72a5edda8d6a:3239。当下次须要发 Request 索要同一个 URI 的时候,浏览器同时收回一个 If-None-Match 报头 (Http RequestHeader) 此时包头中信息蕴含上次访问失去的 Etag:“5d8c72a5edda8d6a:3239″标识。

If-None-Match:“5d8c72a5edda8d6a:3239“

这样,Client 端等于 Cache 了两份,服务器端就会比对 2 者的 etag。如果 If-None-Match 为 False,不返回 200,返回 304(Not Modified) Response。

3、Expires
给出的日期 / 工夫后,被响应认为是过期。如 Expires:Thu, 02 Apr 2009 05:14:08 GMT 需和 Last-Modified 联合应用。用于管制申请文件的无效工夫,当申请数据在有效期内时客户端浏览器从缓存申请数据而不是服务器端. 当缓存中数据生效或过期,才决定从服务器更新数据。

4、Last-Modified 和 Expires
Last-Modified 标识可能节俭一点带宽,然而还是逃不掉发一个 HTTP 申请进来,而且要和 Expires 一起用。而 Expires 标识却使得浏览器罗唆连 HTTP 申请都不必发,比方当用户 F5 或者点击 Refresh 按钮的时候就算对于有 Expires 的 URI,一样也会发一个 HTTP 申请进来,所以,Last-Modified 还是要用的,而且要和 Expires 一起用。

5、Etag 和 Expires
如果服务器端同时设置了 Etag 和 Expires 时,Etag 原理同样,即与 Last-Modified/Etag 对应的 HttpRequestHeader:If-Modified-Since 和 If-None-Match。咱们能够看到这两个 Header 的值和 WebServer 收回的 Last-Modified,Etag 值齐全一样;在齐全匹配 If-Modified-Since 和 If-None-Match 即查看完批改工夫和 Etag 之后,服务器能力返回 304.

6、Last-Modified 和 Etag
分布式系统里多台机器间文件的 last-modified 必须保持一致,免得负载平衡到不同机器导致比对失败. 分布式系统尽量敞开掉 Etag(每台机器生成的 etag 都会不一样)

Last-Modified 和 ETags 申请的 http 报头一起应用,服务器首先产生 Last-Modified/Etag 标记,服务器可在稍后应用它来判断页面是否曾经被批改,来决定文件是否持续缓存

过程如下:
1) 客户端申请一个页面(A)。
2) 服务器返回页面 A,并在给 A 加上一个 Last-Modified/ETag。
3) 客户端展示该页面,并将页面连同 Last-Modified/ETag 一起缓存。
4) 客户再次申请页面 A,并将上次申请时服务器返回的 Last-Modified/ETag 一起传递给服务器。
5) 服务器查看该 Last-Modified 或 ETag,并判断出该页面自上次客户端申请之后还未被批改,间接返回响应 304 和一个空的响应体。

须要留神:
1) Last-Modified 和 Etag 头都是由 WebServer 收回的 HttpReponse Header,WebServer 应该同时反对这两种头。
2) WebServer 发送完 Last-Modified/Etag 头给客户端后,客户端会缓存这些头;
3) 客户端再次发动雷同页面的申请时,将别离发送与 Last-Modified/Etag 对应的 HttpRequestHeader:If-Modified-Since 和 If-None-Match。咱们能够看到这两个 Header 的值和 WebServer 收回的 Last-Modified,Etag 值齐全一样;
4) 通过上述值到服务器端查看,判断文件是否持续缓存;

7、对于 Cache-Control: max-age= 秒 和 Expires
Expires = 工夫,HTTP 1.0 版本,缓存的载止工夫,容许客户端在这个工夫之前不去查看(发申请)
max-age = 秒,HTTP 1.1 版本,资源在本地缓存多少秒。
如果 max-age 和 Expires 同时存在,则被 Cache-Control 的 max-age 笼罩。

Expires 的一个毛病: 就是返回的到期工夫是服务器端的工夫,这样存在一个问题,如果客户端的工夫与服务器的工夫相差很大,那么误差就很大,所以在 HTTP 1.1 版开始,应用 Cache-Control: max-age= 秒代替。

Expires =max-age +“每次下载时的以后的 request 工夫”

所以一旦从新下载的页面后,expires 就从新计算一次,但 last-modified 不会变动.
8、基于 nginx 配置应用总结
分布式系统(有 ng-ha 和 利用的负载平衡), 最好应用 Last-Modified 和 Expires, 把 Etag 敞开掉。
1) 敞开 etag
http {

etag off;
敞开 etag, 应用 Last-Modified 和 Expires
2) 配置 last-modified(默认开启)和 expires
location ~.*.(gif|jpg|jpeg|png|bmp|swf)$

{

expires      30d;

}

location ~.*.(js|css)?$

{

expires      12h;

}
对于配置了多个 location(upstream)的,能够:
location /filebase/ {

root /hskj/file/`;`

autoindex on;

if ($request_filename ~* ^.*?.(txt|doc|pdf|rar|gz|zip|docx|exe|xlsx|ppt|pptx)$){

add_header Content-Disposition: 'attachment;'`;`

}

if ($request_filename ~* ^.*?.(gif|jpg|jpeg|png|bmp|swf)$){

expires      30d;

}

if ($request_filename ~* ^.*?.(js|css)$){

expires      12h;

}

}
成果如下:


这里顺便看一个配置实例: nginx 设置不应用缓存 add_header Cache-Control no-cache
server {

listen       443;

server_name  www.kevin.com;

charset utf-8;

ssl                  on;

ssl_certificate /daka/program/nginx/conf/server.cer;

ssl_certificate_key /daka/program/nginx/conf/server.key;

ssl_session_timeout  5m;

ssl_protocols  SSLv2 SSLv3 TLSv1;

ssl_ciphers  HIGH:!aNULL:!MD5;

ssl_prefer_server_ciphers   on;

# 设置浏览器缓存

add_header Cache-Control no-cache;

add_header Cache-Control private;

location /yp {

proxy_redirect off;

proxy_set_header Host $host;

proxy_set_header X-Real-IP $remote_addr;

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

proxy_pass http://192.168.0.221:8082/yp/yp;

if ($request_filename ~* .*.(html|htm)$)

{

expires -1s;

}

if ($request_filename ~* .*.(gif|jpg|jpeg|png|bmp|swf)$)

{

expires 30d;

}

if ($request_filename ~ .*.(js|css)$)

{

expires 12h;

}

}

location /static {

proxy_redirect off;

proxy_set_header Host $host;

proxy_set_header X-Real-IP $remote_addr;

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

proxy_pass http://192.168.0.221:8082/static;

if ($request_filename ~* .*.(html|htm)$)

{

expires -1s;

}

if ($request_filename ~* .*.(gif|jpg|jpeg|png|bmp|swf)$)

{

expires 30d;

}

if ($request_filename ~ .*.(js|css)$)

{

expires 12h;

}

}

location / {

proxy_redirect off;

proxy_set_header Host $host;

proxy_set_header X-Real-IP $remote_addr;

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

proxy_pass http://192.168.0.221:8080/;

#         if (-e $request_filename){

#           rewrite ^/$ https://www.kevin.com:443/invest/index.jhtml permanent;

#         }

if ($request_filename ~* .*.(html|htm)$)

{

#         expires -1s;

}

if ($request_filename ~* .*.(gif|jpg|jpeg|png|bmp|swf)$)

{

expires 30d;

}

if ($request_filename ~ .*.(js|css)$)

{

expires 12h;

}

}

}

转载文章,如有侵权,分割删除

正文完
 0