經過 HttpHeadersModule 模塊能夠設置HTTP頭,可是不能重寫已經存在的頭,好比可能相對server頭進行重寫,能夠添加其餘的頭,例如:Cache-Control,設置生存期。注意:只有在響應代碼爲 200、20四、30一、302 或 304 時纔有效。一樣須要注意的是,除了 Last-Modified 頭外,該指令能夠在輸出的頭列表中添加一個新的頭,可是不能使用這條指令來重寫已經存在的頭。css
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;