Nginx常用模塊學習---定製HTTP頭信息定製ngx_http_headers_module設置響應頭

Nginx常用模塊學習—定製HTTP頭信息定製ngx_http_headers_module設置響應頭

前言

HTTP頭信息,是實際業務中一個很重要的功能。例如,如果需要將請求結果在瀏覽器上緩存一段時間,或者在請求代理到後端服務器的過程中生成一個唯一的 ID進行識別。通過對 Nginx進行配置,可以輕鬆實現這些功能。
ngx_http_headers_module是在 Nginx編譯時默認自帶的模塊,主要包含 add_header和 expires兩個指令。

使用語法

expires

expires語法: expires [modified] time; expires epoch | max | off;
默認值: expires off;
環境: http、 server、 location、 if in location
用途:設置 Expires和 Cache-Control響應頭字段,主要作用是控制緩存時間,如在瀏覽器上的緩存時間、 CDN的緩存時間。參數值可以是正數、負數或零;

示例如下:

[root@ecs-21d5 nginx]# grep expires  conf/nginx.conf 
    expires 	  -1;   	#輸出響應頭是cache-control:	no-cache
[root@ecs-21d5 nginx]# curl http://127.0.0.1:80/ -I
HTTP/1.1 200 OK
Server: nginx/1.17.4
Date: Wed, 23 Oct 2019 15:05:34 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Wed, 23 Oct 2019 14:56:26 GMT
Connection: keep-alive
ETag: "5db06a1a-264"
Expires: Wed, 23 Oct 2019 15:05:33 GMT
Cache-Control: no-cache
Accept-Ranges: bytes

如果要求在瀏覽器第一次訪問後,數據在瀏覽器上緩存 1h,則配置如下:

[root@ecs-21d5 nginx]# grep -A 1 expires  conf/nginx.conf 
    expires 	  1h;   	# 輸出響應頭是cache-control: max-age=3600
				            # 表示緩存1h,max-age 的單位是秒
[root@ecs-21d5 nginx]# ./sbin/nginx -s stop
[root@ecs-21d5 nginx]# ./sbin/nginx
[root@ecs-21d5 nginx]# curl http://127.0.0.1:80/ -I
HTTP/1.1 200 OK
Server: nginx/1.17.4
Date: Wed, 23 Oct 2019 15:12:29 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Wed, 23 Oct 2019 14:56:26 GMT
Connection: keep-alive
ETag: "5db06a1a-264"
Expires: Wed, 23 Oct 2019 16:12:29 GMT
Cache-Control: max-age=3600
Accept-Ranges: bytes

[root@ecs-21d5 nginx]# 


此配置只能在 HTTP狀態碼是 200、 201、 204、 206、 301、 302、 303、 304、 307或 308時纔會生效。

即只有當請求處於正常的返回狀態時,纔會發送緩存頭,畢竟在瀏覽器上緩存一個錯誤狀態不是什麼好事情。

在 Nginx 1.7.9版本之後, expires指令可以使用變量來配置響應頭,並根據響應頭的 Content-Type來定義緩存時間,也就是可以根據不同的條件動態地調整緩存時間。

例如,如果 Content-Type是 application/ pdf,則添加 cache-control: max-age = 3600響應頭信息;如果 Content-Type是 image/,則添加 ache-control: max-age = 36000響應頭信息;如果沒有匹配到對應的 Content-Type,則執行 default的配置 off,即不進行緩存,代碼如下:

[root@ecs-21d5 nginx]# grep expires -A 4 conf/nginx.conf
    map $sent_http_content_type $expires{
		default			off;
		application/pdf	1h;
		~image			10h; 
    }
    expires 	  $expires;
    
    include       mime.types;
    default_type  application/octet-stream;

[root@ecs-21d5 nginx]# 


在上述配置中, map指令會根據響應頭 Content_ Type的值對 $expires進行賦值(通過 $ sent_ http_ content_ type獲取 Content-Type的值)。

add_ header

語法: add_ header name value [always];
默認值:無
環境: http、 server、 location、 if in location
用途:添加自定義的響應頭。

例如,可以用來添加 Cache-Control響應頭,以達到 expires指令的效果,不過它不如 expires那樣簡潔、明瞭,

示例如下:

[root@ecs-21d5 nginx]# grep add_header conf/nginx.conf
	add_header	Cachae-Control no-cache;		# 等同於 expires -1;
[root@ecs-21d5 nginx]# sbin/nginx -s stop
[root@ecs-21d5 nginx]# sbin/nginx
[root@ecs-21d5 nginx]# 
[root@ecs-21d5 nginx]# 
[root@ecs-21d5 nginx]# curl http://127.0.0.1:80/ -I
HTTP/1.1 200 OK
Server: nginx/1.17.4
Date: Wed, 23 Oct 2019 15:44:52 GMT
Content-Type: text/html
Content-Length: 618
Last-Modified: Wed, 23 Oct 2019 15:26:29 GMT
Connection: keep-alive
ETag: "5db07125-26a"
Cachae-Control: no-cache
Accept-Ranges: bytes

[root@ecs-21d5 nginx]# 
[root@ecs-21d5 nginx]# curl http://127.0.0.1:80/aaa.html -I
HTTP/1.1 404 Not Found
Server: nginx/1.17.4
Date: Wed, 23 Oct 2019 15:46:04 GMT
Content-Type: text/html
Content-Length: 153
Connection: keep-alive

[root@ecs-21d5 nginx]# 


在默認情況下, add_ header只能在 HTTP狀態碼是 200、 201、 204、 206、 301、 302、 303、 304、 307或 308時輸出響應頭,如果出現 404、 500等異常狀態碼則無法輸出響應頭。

但 Nginx 1. 7. 5以上的版本新增了 always參數,使之可以在任何 HTTP狀態下輸出響應頭,示例如下:響應頭信息輸出如下:測試結果表明,即使發生了 500錯誤,加入 always參數後依然可以輸出 add_header響應頭信息。

[root@ecs-21d5 nginx]# vim conf/nginx.conf
[root@ecs-21d5 nginx]# grep add_header conf/nginx.conf
	add_header	Cachae-Control no-cache always;		# 等同於 expires -1;
[root@ecs-21d5 nginx]# sbin/nginx -s reload
[root@ecs-21d5 nginx]# curl http://127.0.0.1:80/a.html -I
HTTP/1.1 404 Not Found
Server: nginx/1.17.4
Date: Wed, 23 Oct 2019 15:48:42 GMT
Content-Type: text/html
Content-Length: 153
Connection: keep-alive
Cachae-Control: no-cache

[root@ecs-21d5 nginx]# curl http://127.0.0.1:80/ -I
HTTP/1.1 200 OK
Server: nginx/1.17.4
Date: Wed, 23 Oct 2019 15:48:50 GMT
Content-Type: text/html
Content-Length: 618
Last-Modified: Wed, 23 Oct 2019 15:26:29 GMT
Connection: keep-alive
ETag: "5db07125-26a"
Cachae-Control: no-cache
Accept-Ranges: bytes

[root@ecs-21d5 nginx]#

實戰經驗

添加請求頭有很多需要注意的地方,下面是在長期使用中總結的一些經驗,供參考。

  • 關於指令 expires 1h

expires 1h表示在瀏覽器上的緩存時間是 1h,但如果缺少 Last-Modified響應頭(文末外鏈說明詳解),大部分瀏覽器不會使用緩存。在業務代碼生成過程中,部分代碼可能沒有使用規範的框架輸出數據,因此可能會缺少 Last-Modified信息,無法在瀏覽器上進行緩存,但請求仍會回源到服務器上,導致帶寬壓力增大。因此負責網絡帶寬和用戶體驗的技術人員要對使用規範進行說明和管理,避免出現緩存效果不理想的情況。

  • 關於指令 add_ header

如果使用 always參數,那麼即使在業務出現異常時,也會輸出 add_ header響應頭信息,因此要慎重使用此參數。另外,如果後端服務器在返回響應體時返回了一個和 add_ header相同的響應頭,則會導致兩個響應頭重複輸出到瀏覽器上,從而引起不必要的 Bug,示例如下:

Last-Modified參考外鏈:

http://harttle.land/2017/04/04/using-http-cache.html

http://blog.csdn.net/eroswang/article/details/8302191

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章