對於不少Nginx初學者來講,配置文件是必需要看懂的。可是當公司的Nginx配置文件放在你面前的時候你總會被一些帶着"$"符號和一大推看不懂的的正則給正懵逼。沒錯帶着"$"好的你們確定是能首先想到這是一個變量,而後就瘋狂的在配置文件裏面找關鍵字,結果一圈照下來啥也沒有,這時候大部分人應該就會憑着感受得判斷這個變量究竟是什麼意思了。其實這也是OK的。可是剩下看不懂正則又應該辦呢。這裏我就給你們整理了Nginx配置文件中常見的一些變量和正則表達式。php
1、Nginx的內置變量html
$arg_PARAMETER 客戶端GET請求中PARAMETER 字段的值android
$args 客戶端請求中的參數nginx
$binary_remote_addr 遠程地址的二進制表示web
$body_bytes_sent 已發送的消息體字節數正則表達式
$content_length HTTP請求信息中content-length的字段chrome
$content_type 請求信息中content-type字段後端
$cookie_COOKIE 客戶端請求中COOKIE頭域的值瀏覽器
$document_root 針對當前請求的根路徑設置值緩存
$document_uri 與$uri相同
$host 請求信息中的host頭域,若是請求中沒有Host行,則等於設置的服務器名
$http_HEADER HTTP請求信息裏的HEADER地段
$http_host 與$host相同,可是若是請求信息中沒有host行,則可能不一樣客戶端cookie信息
$http_cookie 客戶端cookie信息
$http_referer 客戶端是從哪個地址跳轉過來的
$http_user_agent 客戶端代理信息,也就是你客戶端瀏覽器
$http_via 最後一個訪問服務器的IP
$http_x_forwarded_for 至關於訪問網路訪問的路徑
$is_args 若是有args的值,則等於"?",不然爲空
$limit_rate 對鏈接速率的限制
$nginx_version 當前Nginx的版本
$pid 當前Nginx服務器的進程的進程ID
$query_string 與$args相同
$remote_addr 客戶端IP地址
$remote_port 客戶端的端口
$remote_user 客戶端的用戶名,用於 auth basic module驗證
$request 客戶端請求
$request_body 客戶端發送的報文體
$request_body_file 發送後端服務器的本地臨時緩存文件的名稱
$request_filename 當前請求的文件路徑名,由root或alias指令與URI請求生成
$request_method 請求後端數據的方法,例如"GET","POST"
$request_uri 請求的URI,帶參數,不包含主機名
$scheme 所用的協議,如http或者HTTPS,好比rewrite^(.+)$$scheme://mysite.name$redirect
$sent_http_cache_control 對應http請求頭中的Cache-Control,須要打開chrome瀏覽器,右鍵檢查,選中network,點中其中一個請求的資源
$sent_http_connection 對應http請求中的Connection
$sent_http_content_type 對應http請求中的Content-Type
$sent_last_modified 對應請求中的Last-Modified
$server_addr 服務端的地址
$server_port 請求到達服務器端口號
$server_protocol 請求協議的版本號,HTTP1.0/HTTP1.1
$uri 請求的不帶請求參數的URI,可能和最初的值有不一樣,好比通過重定向之類的
若是上面的變量尚未找到你想要的結果能夠點擊右邊的這個Nginx官方連接地址--->http://nginx.org/en/docs/varindex.html
2、正則表達式
* 零次或者屢次匹配前面的字符表達式,等效於{0,}.; zo*與「z」和「zoo」匹配
+ 一次或者屢次匹配前面的字符表達式,等效於{1,};zo+與「zoo」匹配可是與「z」不匹配
? 零次或一次匹配前面的字符或子表達式。當該字段緊隨任何其餘限定符(*、+、?、{n}、{n,}或{n,m})以後時,匹配模式是很是貪婪的,非貪婪模式匹配搜索到的、儘量少的字符串,而默認的貪婪模式匹配搜索到的、儘量多的字符串。zo? 與「z」和「zoo」不匹配;o+?只於「oooooo」中的單個o匹配。而o+與全部的「o」匹配。do(es)?與do或者does中的do匹配
^ 匹配搜索字符串以什麼開始。若是將^用做括號表達式中的第一個字符,則會對字符集求反,^\d{3}與搜索字符串開始出的3個數字匹配。[^abc]與除abc覺得的任何字符匹配
$ 匹配搜索字符串以什麼結尾,\d{3}$匹配任何3個數字結尾的
. 額這裏實際上是一個點號;匹配除了換行符\n以外的任何單個字符
[] 標記括號表達式的開始和結尾,[1-4]與1,2,3,4匹配。[^aAeE],除了a,A,e,E以外的匹配
{} 標記限定符表達式的開始結尾,a{2,3}匹配「aa」和「aaa」
() 標記子表達式的開始和結尾,Nginx服務器使用該元字符保存自表達式以備未來之用A(\d)與「A0」到「A9」匹配,並保存成一個參數
| 這個就能夠理解成爲一個或匹配了;z|food|cunt 匹配z,food ,cunt
/ 此標識符通常在location中 若是一個/就表示默認匹配這個虛擬主機中的全部資源
\b 與一個字邊界匹配,即字與空格間的位置 er\b "never" 中的「er」匹配,但與'verb"中的「er」不匹配
\B 非邊界字符匹配,與\b相反
\D 匹配非數字
\w 匹配任意字符
\W 排除A-Z a-z 0-9和下劃線之外的任意字符匹配
[a-z] 匹配小寫字符
[^a-z] 反字符範圍,與上面相反
{n} 正好匹配n次,n是非負整數;o{2}不匹配boy,可是匹配food
{n,} 至少匹配n次
{n,m} 匹配至少n次,最多m次
^和$ 指定搜索字符串的開始和結束爲止,這將在搜索字符串包含匹配字符串以外的任何字符時阻止匹配
一些特別的模式修飾符:
(?i) 即匹配時不區分大小寫。表示匹配時不區分大小寫。
(?s) 即Singleline(單行模式)。表示更改.的含義,使它與每個字符匹配(包括換行 符\n)。
(?m) 即Multiline(多行模式) 。 表示更改^和$的 含義,使它們分別在任意一行的行首和行尾匹配,而不只僅在整個字符串的開頭和結尾匹配。(在此模式下,$的 精確含意是:匹配\n以前的位置以及字符串結束前的位置.)
(?x) 表示若是加上該修飾符,表達式中的空白字符將會被忽略,除非它已經被轉義。
(?e) 表示本修飾符僅僅對於replacement有用,表明在replacement中做爲PHP代碼。
(?A) 表示若是使用這個修飾符,那麼表達式必須是匹配的字符串中的開頭部分。好比說"/a/A"匹配"abcd"。
(?E) 與"m"相反,表示若是使用這個修飾符,那麼"$"將匹配絕對字符串的結尾,而不是換行符前面,默認就打開了這個模式。
(?U) 表示和問號的做用差很少,用於設置"貪婪模式"。
Nginx做爲一款主流的web服務器,功能強大,在處理請求的方式上也是很是給力的。通常變量和正則出現較多的地方是location區域中,或者是定義日誌輸出的format格式中。
例子一:Wap端訪問PC端域名自動跳轉
這個案例的需求是這樣子的,假如我使用手機端訪問www.baidu.com這條域名,則幫我自動重寫爲m.baidu.com。而我訪問www.souhu.com這條域名,則幫我重寫爲m.souhu.com這條域名。
if ( $server_name ~ ((|www.|)([if ( $ser| #過濾主域名 if ( $server_name ~ ((www.|)([\S\s]*)) ) { set $domain $3; } #設定初始值 set $temp 0; #判斷是否爲支付域名 if ( $host ~* (pay|zf) ) { set $temp "${temp}1"; } #判斷是不是手機端 if ($http_user_agent ~* (mobile|nokia|iphone|ipad|android|samsung|htc|blackberry)) { set $temp "${temp}2"; } #判斷是否跳轉 if ( $temp = "02" ) { rewrite ^(.*) https://app.$domain permanent; }
分析過程:
首先,咱們是須要取得主域名部分,那就少不了使用正則去匹配,假如說以www.baidu.com這條域名爲例,咱們看到的第一個就是www.這個字段,可是還會存在一種狀況就是用戶可能會直接輸入baidu.com這樣子去訪問,因此咱們這裏是用(www.|)去進行匹配,再而後匹配點這個字段,而下面的$3是表示取第三個括號裏的值,最後復值給$a這個變量,接下來就是經過$http_user_agent這個內置變量去進行判斷用戶是使用什麼方式訪問,而後在進行重定向操做。
例子二:Nginx的IP白名單
這個案例的需求是這樣子的,咱們的後臺訪問只容許特定的IP進行訪問,假如說別的IP進行訪問的話咱們將進行跳轉到一個別的報錯頁面,或者直接跳轉回首頁
#定義初始值 set $my_ip 0; #判斷是否爲指定的白名單 if ( $http_x_forwarded_for ~* "10.0.0.1|172.16.0.1" ){ set $my_ip 1; } #不是白名單的IP進行重定向跳轉 if ( $my_ip = 0 ){ rewrite ^/$ /40x.html; }
分析過程:
這個其實和上面的判斷用戶是使用電腦訪問仍是手機訪問是同樣的,但惟一的區別在於內置變量不一樣,在Nginx中的內置變量裏面$http_x_forwarded_for即是爲客戶訪問的真實ip地址,因此咱們使用這個內置變量進行判斷就行了,同時添加多了一個初始值;
例子三:重寫Url地址,隱藏提交內容
這個案例的需求是這樣子的,咱們提交一些表單內容後url地址會顯示除部分參數,好比http://baidu.com/index.php?user=admin&pass=123,而咱們須要將url重寫爲http://baidu.com/index
rewrite ^/(\w+)/(\w+)/z(\d+) /$1/$2/$3/$arg_x/$arg_y? permanent; rewrite ^/(\w+)/(\w+)/(\d+)/(\d+)/(\d+) /$1/$2/$3/$4_$5.png permanent;
分析過程:
首先咱們想一想想url的演變,http://baidu.com/index.php?user=admin&pass=123 => http://baidu.com/index.php/user/admin/pass/123 => http://baidu.com/index,而後咱們根據演變進行一步一步的操做,nginx rewrite正則匹配不會匹配問號後的參數,所以須要使用$arg_{參數名}來保留參數,且匹配規則要以問號結尾;最後匹配一些其餘項替換就完成重寫了