NGINX經常使用指令

最近常常用到nginx,因此想着系統的看一下經常使用的指令html

HttpCore指令集

server_name

含義:設置虛擬服務器的名字,第一個名字將成爲主服務器名稱;服務器名稱可使用*代替名稱的第一部分或者最後一部分;也可使用正則表達式進行捕獲,目前不經常使用nginx

示例正則表達式

server {
    server_name example.com *.example.com www.example.*;
}
# 使用正則
server {
    server_name ~^(www\.)?(.+)$;

    location / {
        root /sites/$2;
    }
}

location

含義:根據URI設置配置,可使用合法的字符串或者正則表達式算法

語法:location [=|~|~*|^~] /uri/ { ... }緩存

上下文:server服務器

匹配符 含義
= 精確匹配
~ 正則,大小寫敏感
~ 正則,大小寫不敏感
^~ 前綴匹配

示例cookie

location = /ceshi1/ {
    proxy\_pass http://127.0.0.1:7001/xxxx;
    # /ceshi1 -> /xxxx
    # /ceshi1/a -> 404 Not Found
    # /ceshi1a -> 404 Not Found
}
location ^~ /ceshi2/ {
    proxy\_pass http://127.0.0.1:7001/xxxx;
    # /ceshi2 -> /xxxx
    # /ceshi2/a -> /xxxxa
    # /ceshi2a -> 404 Not Found
}

詳細對比測試見附錄測試

經常使用變量

變量名 含義
$arg_PARAMETER GET請求的參數,PARAMETER爲參數名
$args/$query_string GET請求的query_string,好比/test?xxxx=ceshi1&yyyy=ceshi2,則$args爲xxxx=ceshi1&yyyy=ceshi2,$args_xxxx爲ceshi1
$content_type 請求頭Content-Type
$cookie_COOKIE 名稱爲COOKIE的cookie
$host 按照如下優先順序:來自請求行的主機名,來自 Host 請求頭字段的主機名,或與請求匹配的服務器名
$https 若是鏈接以 SSL 模式運行,則爲 on,不然爲空字符串
$is_args 若是請求行有參數則爲 ?,不然爲空字符串
$http_HEADER 獲取請求頭字段,注意要將中劃線給爲下劃線,示例爲$http_user_agent, $http_referer
$remote_addr 客戶端地址
$remote_port 客戶端端口
$request_method 請求方法
$request_uri 完整的原始請求URI(帶參數)
$scheme 請求模式,http或https
$status 響應狀態
$uri/$document_uri 請求的url path,可能和初始不一樣,好比使用rewrite

HttpUpstream指令集

該模塊用於定義可被proxy_pass等指令應用的服務器組url

upstream

含義:定義一組服務器,服務器能夠監聽不一樣端口。代理

示例

upstream backend {
    server backend1.example.com weight=5;
    server 127.0.0.1:8080       max_fails=3 fail_timeout=30s;
    server unix:/tmp/backend3;
 
    server backup1.example.com  backup;
}
server {
    location / {
        proxy_pass http://backend;
    }
}

默認狀況下,使用加權輪詢均衡算法在服務器間分配請求。在上面的示例中,每 7 個請求將按以下方式分發:5 個請求轉到 backend1.example.com,另外 2 個請求分別轉發給第二個和第三個服務器。若是在與服務器通訊期間發生錯誤,請求將被傳遞到下一個服務器,依此類推,直到嘗試完全部正常運行的服務器。若是沒法從這些服務器中得到成功響應,則客戶端將接收到與最後一個服務器的通訊結果。

server

含義:定義服務器地址和其餘參數

HttpRewrite指令集

rewrite

含義:根據正則表達式修改URL或者修改字符串,注意,重寫表達式只對相對路徑有效,若是你想匹配主機名,應該使用if語句

使用位置:server或者location或者if

語法:rewrite regex replacement flag

關於flag

含義
last 中止當前請求,並根據該次修改從新發起請求,而後走一遍這個配置文件
break 替換後繼續往下執行指令(完成rewrite指令集)
redirect 臨時重定向,返回302
permanent 永久重定向,返回301

關於參數

若是不想讓匹配的內容的參數附在重定向的後面,則在最後加一個問號,以下

rewrite  ^/users/(.*)$  /show?user=$1?  last;

工程示例

rewrite . /test/index.html break; # 轉發全部的請求給index.html頁面,並完成全部的rewrite指令集

break

含義:完成全部的rewrite指令集

使用位置:server,location,if

if

含義:邏輯判斷

使用位置:server,location

語法:if(condition){}

比較符

符號 含義
= 相等
!= 不等
~* 正則匹配,大小寫不敏感
~ 正則匹配,大小寫敏感
!~* 不符合,大小寫不敏感
!~ 不符合,大小寫敏感
-f and !-f 判斷文件存在或者不存在
-d and !-d 檢測一個目錄是否存在
-e and !-e 檢測是否存在一個文件,一個目錄或者一個符號連接
-x and !-x 檢測一個文件是否可執行

示例

set $xsrfToken "";
    if ($http_cookie ~* "XSRF-TOKEN=(.+?)(?=;|$)"){
    set $xsrfToken $1; # 設置變量xsrfToken爲cookie中匹配到的值
}

set

含義:設置變量的值

使用位置(上下文):server,location,if

示例:如上

return

含義:返回一個狀態值給客戶端

使用位置(上下文):server,location,if

示例:

if ($invalid_referer) { # 檢測到Referers不合法,則禁止訪問,返回403
    return 403;
}

HttpProxy指令集

proxy_pass

含義:設置代理服務器的協議、地址以及映射位置的可選URL,協議能夠指定http或https,能夠將地址指定爲域名或IP地址,以及一個可選端口號;若是域名解析爲多個地址,則全部這些地址將以輪詢方式使用;能夠將地址指定爲upstream

使用位置 http -> server -> location

語法:proxy_pass URL

轉發時,URI的傳遞方式以下

  • 若是proxy_pass指定了URI,則轉發時會將location匹配的規則部分替換爲URI部分

    location /name/ {
        proxy_pass http://127.0.0.1/remote/; # http://a.com/name/test -> http://127.0.0.1/remote/test
    }
  • 若是proxy_pass沒有指定URI,則請求URL將會以location匹配爲準,示例以下

    location /xxxx {
        proxy_pass http://127.0.0.1; # 將http://a.com/xxxx/test -> http://127.0.0.1/xxxx/test
    }

例外狀況,沒法肯定怎麼替換URI

  • location使用正則匹配,proxy_pass不使用URI
  • 使用rewrite,將忽略proxy_pass中的URI

proxy_set_header

含義:設置請求頭內容

語法:proxy_set_header header value

使用位置:http,server,location

proxy_set_header X-XSRF-TOKEN $xsrfToken;

proxy_connect_timeout

含義:定義與代理服務器創建鏈接的超時時間,注意,次超時時間一般不會超過75s

proxy_connect_timeout 60;

proxy_send_timeout

含義:設置將請求傳輸到代理服務器的超時時間。超時時間僅做用於兩個連續的寫操做之間,而不是整個請求的傳輸過程。若是代理服務器在該時間內未收到任何內容,則關閉鏈接。

proxy_send_timeout 60;

proxy_read_timeout

含義:定義從代理服務器讀取響應的超時時間。該超時時間僅針對兩個連續的讀操做之間設置,而不是整個響應的傳輸過程。若是代理服務器在該時間內未傳輸任何內容,則關閉鏈接。

proxy_read_timeout 60;

HttpHeaders指令集

add_header

含義:增長響應頭內容

使用位置 http -> server -> location

語法: add_header name value;

add_header Cache-Control 'no-store'; # 設置全部內容不會被緩存

expires

含義:增長響應頭Expires字段,便於肯定緩存時間

使用位置:http -> server -> location

語法:expires [time|epoch|max|off]

含義
time 數量
epoch 1 January, 1970, 00:00:01 GMT
max Cache-Control值爲10年,Expires爲31 December 2037 23:59:59 GMT
off 【默認值】不使用時間
expires off; #不使用過時時間

注意1:優先級 強緩存優先級 > 對比緩存優先級 ;對於強緩存優先級,pragma > Cache-Control > Expires;對於對比緩存優先級,ETag > Last-Modified

注意2:Cache-Control是http1.1的頭字段,Expires是http1.0的頭字段,建議二者都寫

注意3:Cache-Control默認值爲private,其餘細節不贅述

細節參考:https://www.imooc.com/article...

HttpReferer指令集

valid_referers

含義:判斷請求頭Referers的正確性,結果會賦值給$invalid_referer

使用位置:http -> server -> location

語法:valid_referers [none|blocked|server_names]

含義
none 無Referer,通常直接刷新會是如此
blocked 有,可是被刪除,這些值不以http://或者https://開頭
server_names 寫一個匹配的路徑規則,要帶域名,會從scheme後面開始匹配,端口也會忽略,寫正則以~開頭
location /views {
    valid_referers *.com/chart/; #判斷Referer是否匹配給出的路徑,匹配則$invalid_referer爲false,不然爲true
    if ($invalid_referer) {
        return 403;
    }
}
# 若是Referer爲a.com/chart/1則符合規則,若是爲a.com/chart則不符合,若是沒有referer也不符合

附錄:location/proxy_pass/rewrite對比使用總結

將location和proxy_pass的全部匹配狀況測試結果放在下面,對應關係爲【訪問path -> 轉發成的path】

location /test1 {
    proxy_pass http://127.0.0.1:7001/;
    # /test1 -> /
    # /test1/a -> //a
    # /test1a -> /a
}
location /test2 {
    proxy_pass http://127.0.0.1:7001/xxxx;
    # /test2 -> /xxxx
    # /test2/a -> /xxxx/a
    # /test2a -> /xxxxa
}
location /test3 {
    proxy_pass http://127.0.0.1:7001/xxxx/;
    # /test3 -> /xxxx//
    # /test3/a -> /xxxx//a
    # /test3a -> /xxxx/a
}
location /test4 {
    proxy_pass http://127.0.0.1:7001;
    # /test4 -> /test4
    # /test4/a -> /test4/a
    # /test4a -> /xxxx4a
}
location /test5/ {
    proxy_pass http://127.0.0.1:7001/;
    # /test5 -> /
    # /test5/a -> /a
    # /test5a -> 404 Not Found
}
location /test6/ {
    proxy_pass http://127.0.0.1:7001/xxxx;
    # /test6 -> /xxxx
    # /test6/a -> /xxxxa
    # /test6a -> 404 Not Found
}
location /test7/ {
    proxy_pass http://127.0.0.1:7001/xxxx/;
    # /test7 -> /xxxx/
    # /test7/a -> /xxxx/a
    # /test7a -> 404 Not Found
}
location /test8/ {
    proxy_pass http://127.0.0.1:7001;
    # /test8 -> /test8/
    # /test8/a -> /test8/a
    # /test8a -> 404 Not Found
}
location /test9/ {
    rewrite . /b break;
    proxy_pass http://127.0.0.1:7001/xxxx;
    # /test9 -> /b
    # /test9/a -> /b
    # /test9a -> 404 Not Found
}
location ~* /test10(.*)/ {
    #proxy_pass http://127.0.0.1:7001/xxxx;
    # nginx沒法執行經過,會報錯,不能帶URI
}

location = /ceshi1/ {
    proxy_pass http://127.0.0.1:7001/xxxx;
    # /ceshi1 -> /xxxx
    # /ceshi1/a -> 404 Not Found
    # /ceshi1a -> 404 Not Found
}
location ^~ /ceshi2/ {
    proxy_pass http://127.0.0.1:7001/xxxx;
    # /ceshi2 -> /xxxx
    # /ceshi2/a -> /xxxxa
    # /ceshi2a -> 404 Not Found
}
相關文章
相關標籤/搜索