Nginx - Header详解

1. 前言

经过 HttpHeadersModule 模块能够设置HTTP头,可是不能重写已经存在的头,好比可能相对server头进行重写,能够添加其余的头,例如:Cache-Control,设置生存期。注意:只有在响应代码为 200、20四、30一、302 或 304 时才有效。一样须要注意的是,除了 Last-Modified 头外,该指令能够在输出的头列表中添加一个新的头,可是不能使用这条指令来重写已经存在的头。css

 

2. HttpHeadersModule模块

 

2.1 指令nginx

 

指令名称:add_header浏览器

语法:add_header name value缓存

默认值:none服务器

使用环境:http、server、location负载均衡

功能:为HTTP 响应添加头分布式

 

指令名称:expiresspa

语法:expires [modified] time |  epoch | max | off;3d

默认值:expires off代理

使用环境:http、server、location、if in location

功能:该指令用于控制是否在响应中添加一个生存期标志

  off:阻止改变 Expires 和 Cache-Control 头

  max:设置 Expires 头为 2037年,并设置 Cache-Control 头的 max-age 值设为 10 年,若是设置为一个非负数或者是一个时间值,那么会将 Cache-Control头的 max-age=#,即将 max-age 的值设置为 '#',这里的 '#' 将非负数或时间值转换成秒数

 

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

 

2.2 浏览器中关于 Cache 的 3 种属性

 

1. Cache-Control

设置相对过时时间,max-age指明以秒为单位的缓存时间,若对静态资源只缓存一次,能够设置max-age的值为315360000000 (1万年)。

 

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设定范围内,若是服务器页面发生了变化,客户端是不会获取新的修改数据,这时须要客户端进行刷新来获取才行。

 

3. Last-Modifed

该资源是最后修改时间,在浏览器下一次请求资源时,浏览器将先发送一个请求到服务器上,并附上 If-Unmodified-Since 头来讲明浏览器所缓存资源的最后修改时间,若是服务器发现没有修改,则直接返回304(Not Modified)回应信息给浏览器(内容不多,几乎为0),若是服务器对比时间发现修改了,则照常返回所请求的资源。

 

须要注意:

  (1)Last-Modified属性一般和Expires或Cache-Control属性配合使用,由于即便浏览器设置为缓存,当用户点击“刷新”按钮时,浏览器会忽略缓存向服务器发送请求,这Last-Modified将可以很好的减小回应开销。

  (2)Etag将返回给浏览器一个资源ID,若是有了新版本则正常发送并附上新ID,不然返回304,可是在服务器集群状况下,每一个服务器将返回不一样的ID,所以不建议使用etag。

 

nginx 集群模式下禁止 etag:

 

以上描述的客户端浏览器缓存是指存储位置在客户端浏览器,可是对客户端浏览器缓存的实际设置工做是在服务器上资源中完成的。虽然上面介绍了有关于客户端浏览器缓存的属性,可是实际上对这些属性的设置工做都须要在服务器的资源中作设置。

我的理解的max-age意思是:客户端本地的缓存,在配置的生存时间内的,客户端能够直接使用,超出生存时间的,到服务器上取新数据。固然这些还要看客户端浏览器的设置。

并且浏览器的缓存行为和用户的操做也有关系:

 

4. 浏览器缓存

  (1)expires

  (2)cache-control

  (3)last-modified

  (4)etag

 

每一个状态的详细说明:

 

1. expires

 

expires 用于设置缓存过时时间,这里设置 expires =1m 也就是缓存60秒,这60秒钟,若是用户是地址栏回车操做,连接会返回HTTP 200状态,可是不会去服务器获取数据,就算服务器页面发生了修改,也要等待 expires 时间结束,才会去服务器对比 Last-Modified 时间。若是用户的操做是直接刷新,那么每次都会去服务器对比 Last-Modified时间。所以,服务器设置的缓存,与用户的操做息息相关

 

2. Last-Modified

 

在浏览器第一次请求某一个URL时,服务器端的返回状态会是200,内容是你请求的资源,同时有一个Last-Modified的属性标记(HttpReponse Header)此文件在服务器端最后被修改的时间。客户端第二次请求此URL时,根据HTTP协议的规定,浏览器会向服务器传送If-Modified-Since报头(HttpRequest Header),询问该时间以后文件是否有被修改,若是服务器端的资源没有变化,则自动返回HTTP304(NotChanged.)状态码,内容为空,这样就节省了传输数据量。当服务器端代码发生改变或者重启服务器时,则从新发出资源,返回和第一次请求时相似。从而保证不向客户端重复发出资源,也保证当服务器有变化时,客户端可以获得最新的资源。

 

3. etag 工做原理

HTTP协议规格说明定义ETag为“被请求变量的实体标记”。简单点即服务器响应时给请求URL标记,并在HTTP响应头中将其传送到客户端,相似服务器端返回的格式:

 

若是ETag没改变,则返回状态304。当下次须要发Request索要同一个URI的时候,浏览器同时发出一个If-None-Match报头(Http RequestHeader)此时包头中信息包含上次访问获得的Etag标识。这样,Client端等于Cache了两份,服务器端就会比对2者的etag。若是If-None-Match为False,不返回200,返回304(Not Modified) Response。

 

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应该同时支持这两种header

  (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不会变化.

 

2.3 示例

配置 last-modified(默认开启)和expires

location ~.*\.(gif|jpg|jpeg|png|bmp|swf)$ { expires 30d; } location ~.*\.(js|css)?$ { expires 12h; }

 

发起请求,查看 header信息:

 

若是处于频繁调试阶段,可将 expires 设置为 -1s  或者 Cache_Control no-cache

add_header expires -1s;
或者
add_header Cache-Control no-cache;

相关文章
相关标签/搜索