nginx中location對url匹配;php
語法:location [=|~|~*|^~] /uri/ { … }html
當匹配中符合條件的location,則執行內部指令;若是使用正則表達式,必須使用~*代表不區分大小寫或者~區分大小寫匹配;例如:location ~* \.(gif|jpg|jpeg)$ ;當配皮成功後,將中止往下匹配;若是沒有找到,則使用常規自字符串處理結果;nginx
若是不是用正則表達式;可以使用=嚴格匹配;web
若是使用^~前綴用於一個常規字符串;表示若是路徑匹配,則不測試正則表達式;正則表達式
總結:指令按下列順序被接受chrome
1:=前綴的指令嚴格匹配這個查詢;若是找到中止往下匹配express
2:掙下的常規字符串,長的在前,若是這個匹配使用^~前綴,匹配中止;瀏覽器
3:正則表達式,按配置文件的順序;服務器
4:若是第三步產生匹配。則使用這個結果;中止匹配;不然使用第二部的匹配結果;cookie
四個案例:
location = / { #只匹配/查詢 } location / { #匹配任何查詢,全部請求都是以/開頭。可是正則表達式規則和長的塊規則將被優先匹配和查詢; } location ^~ /images/ { # 匹配任何已 /images/ 開頭的任何查詢而且中止搜索。任何正則表達式將不會被測試。 } location ~* \.(gif|jpg|png)${ #匹配任何以gif、jpg、png結尾的請求。而後全部/images/目錄的請求將使用第三個 } 例子請求: / -> configuration A /documents/document.html -> configuration B /images/1.gif -> configuration C /documents/1.jpg -> configuration D
八個location案例
location = / { #精確匹配,/後面不能加任何字符串,符合此條件就直接返回數據,再也不像下匹配。 if (-d $request_filename) { root /usr/local/nginx/html/; #當用戶訪問newweb的時候,則顯示此目錄的內容,除此以外訪問其餘的任何目錄都不匹配。 [動做A] } location / { # 由於全部的地址都以/開頭,因此這條規則將匹配到全部請求,可是非精確匹配會採起正則和最長字符串會優先匹配,所以還會向下繼續匹配,好比當訪問/bbs的時候,還須要看下面是否更精確的匹配。 [ 動做B] } location /documents/ { # 匹配任何以 /documents/ 開頭的地址,匹配符合之後,還要繼續往下搜索 # 若是後面的正則表達式都沒有匹配到,就匹配這一條 [動做C] } location ^~ /images/ { #匹配任何以/images/ 開頭的任何請求而且中止搜索,後面任何正則表達式將不會被測試。 # 匹配任何以 /images/ 開頭的地址,匹配符合之後,中止往下搜索正則,採用這一條。 [動做D] } location ~* \.(gif|jpg|jpeg)$ { #~*爲不區分大小寫 # 匹配全部以 gif,jpg或jpeg 結尾的請求 # 然而,全部請求/images/下的圖片會被動做D匹配處理,由於動做D有^~會優先匹配並終止匹配,因此到達不了這一條正則 [動做E] } location /images/ { # 字符匹配到 /images/,繼續往下,會發現 ^~ 存在,若是動做D存在,則這一條就不生效。 [動做F] } location /images/abc { #最長字符匹配到 /images/abc,繼續往下,會發現 ^~ 存在,若是D存在,則這一條就不生效。 #F與G的放置順序是沒有關係的 [動做G] } location ~ /images/abc/ { # 動做D存在,這一條不生效,若是註銷動做D,則會優先最長匹配 動做G 開頭的地址,而後向下匹配,到這一條的時候就會匹配並生效。 [ configuration H ] } 匹配優先級,順序 no優先級: (location =) > (location 完整路徑) > (location ^~ 路徑) > (location ~,~* 正則順序) > (location 部分起始路徑) > (/) 上面的匹配結果 按照上面的location寫法,如下的匹配示例成立: / -> config A 精確徹底匹配,即便/index.html也匹配不了 /downloads/download.html -> config B 匹配B之後,往下沒有任何匹配,採用B /images/1.gif -> configuration D 匹配到F,往下匹配到D,中止往下 /images/abc/def -> config D 最長匹配到G,往下匹配D,中止往下 你能夠看到 任何以/images/開頭的都會匹配到D並中止,FG寫在這裏是沒有任何意義的,H是永遠輪不到的,這裏只是爲了說明匹配順序 /documents/document.html -> config C 匹配到C,往下沒有任何匹配,採用C /documents/1.jpg -> configuration E 匹配到C,往下正則匹配到E /documents/Abc.jpg -> config CC 最長匹配到C,往下正則順序匹配到CC,不會往下到E
當匹配成功後location中可使用rewrite進行路由重寫;
首先須要瞭解nginx rewrite中可使用到的全局變量;
$args :請求中get的參數,例如a=1&b=2;
$body_remote_add :二進制客戶地址
$body_byte_sent :相應時發送出去的body字節數數量,即便連接中斷這個數據也是精確的;
$content_length :請求頭中的Content_length字段
$content_type :請求中的Content_type字段
$document_root :當前請求在root指令中的位置;服務器中絕對路徑
$document_url :與uri相同
$host :請求主機頭字段,不然爲服務器名稱;
$hostname :保存了當前請求中不包含指令的uri,例如:http://www.aaa.com/index.php?a=1中的/index.php;
$host :請求的服務器名稱;
$http_user_agent :客戶端瀏覽器的詳細信息,若是使用 chrome 和Firefox 則訪問結果是
Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.87 Safari/537.36 #chrome的瀏覽器信息 Mozilla/5.0 (Windows NT 6.1; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0 #Firefox的瀏覽器信息
$http_cookie : 客戶端cookie信息;
$limit_rate :若是nginx服務器中使用limit_rate配置了顯示網絡速率,則會顯示,若是沒有則爲0
$remote_addr :客戶端的地址,每一個客戶端的公網ip,
$remote_port :客戶端請求nginx服務器時隨機打開的端口,這個每一個客戶端本身的端口;
$remote_user :已經通過auth basic module驗證的用戶名
$request_body_file :做反向代理是發給服務端的本地資源名稱
$request_method :請求志願的方式,get\put\delete等
$request_filename :請求的資源文件的路徑名稱
$request_url :請求參數的原始uri,不包含主機名;如"/index.php?a=1"
$squery_string :保存了url請求的指令,與$args相同
$scheme :請求協議;如http、https、ftp
$server_protacpl :保存了客戶端請求資源使用的協議的版本,如http/1.0、http/1.1
$server_addr :保存了服務器ip
$server_name :保存了服務器的主機名;該變量不必定是用戶訪問的域名,是你的server_name配的地址;
$host :保存了用戶訪問的域名
$server_port :服務器端口
$uri與$document_uri相同 :不包含指令的uri地址
如www.aaa.com/index.php?a=1&b=2中的index.php
防盜鏈:注意location生效規則,不然防盜鏈不起做用。
配置參數說明:
none
'Referer' :來源頭部爲空的狀況
blocked
'Referer' :來源頭部不爲空,但裏面的值被代理或者防火牆刪除,這些值都不以http://或者https://開頭
server_names
'Referer' :來源頭部包含當前的server_name,就是域名
arbitary string :任意字符串,定義服務器名或者可選的url前綴,主機名可使用*開頭或者結尾,在檢測來源頭部這個過程當中,來源域名中的主機端口將會被忽視;
regular expression :正則表達式,表示排除https://或者http://開頭的字符串
下面兩個案例:
location ~* \.(gif|jpg|png|bmp)$ { valid_referers none blocked *.aaa.com server_names ~\.google\. ~\.baidu\.; if ($invalid_referer) { return 403; #rewrite ^/ http://www.aaa.com/1.jpg; } }
以上全部來至aaa.com和域名中包含google和baidu的站點均可以訪問到當前站點的圖片,若是來源域名不在這個列表中,那麼$invalid_referer等於1,在if語句中返回一個403給用戶,這樣用戶便會看到一個403的頁面,若是使用下面的rewrite,那麼盜鏈的圖片都會顯示403.jpg。若是用戶直接在瀏覽器輸入你的圖片地址,那麼圖片顯示正常,由於它符合none這個規則.
location ~* \.(gif|jpg|png|swf|flv)$ { # 防盜鏈設置,對於後綴是gif、jgp等格式的生效 valid_referers none blocked a.com *.a.com; #定義容許訪問的請求連接 if ($invalid_referer) { return 404; } } none:在瀏覽器輸入網站域名直接訪問的請求,須要容許訪問的 blocked:有referer首部,可是referer首部被清除了,通常是防火牆改過的請求 server_name:帶服務器名稱的,通常是本機或其餘服務器的請求,a.com和*.a.com是本公司的域名,要容許訪問因而要先容許本機的訪問,再禁止其餘服務器的訪問
location /public/admin/images/y.jpg { #valid_referers none blocked *.aaa.com server_names *.aaa.com ; #valid_referers none blocked www.sss.com; #設置只有該域> 名能夠訪問 valid_referers none blocked 111.111.111.11; #設置只有該域名能夠訪> 問 if ($invalid_referer) { rewrite ^ http://baidu.com$request_uri?; return 403; rewrite ^/ http://www.aaa.com/1.jpg; } }
經常使用正則匹配
. : 匹配除換行符之外的任意字符 ? : 重複0次或1次 + : 重複1次或更屢次 * : 重複0次或更屢次 \d :匹配數字 ^ : 匹配字符串的開始 $ : 匹配字符串的介紹 {n} : 重複n次 {n,} : 重複n次或更屢次 [c] : 匹配單個字符c [a-z] : 匹配a-z小寫字母的任意一個 小括號()之間匹配的內容,能夠在後面經過$1來引用,$2表示的是前面第二個()裏的內容。正則裏面容易讓人困惑的是\轉義特殊字符。
參考if判斷語句
if ($http_user_agent ~ MSIE) { #若是客戶端是微軟的IE瀏覽器,就將請求rewrite到msie目錄下。 rewrite ^(.*)$ /msie/$1 break; } if ($http_cookie ~* "id=([^;]+)(?:;|$)") { # 若是cookie匹配正則,就設置變量$id等於正則引用部分 set $id $1; 設置$id等於正則第一個括號內匹配的部分 } if ($request_method = POST) { #若是提交方法爲POST,則返回狀態405(Method not allowed)。return不能返回301,302 return 405; } if ($slow) { #限速,$slow能夠經過 set 指令設置 limit_rate 10k; } if (!-f $request_filename){ #若是請求的文件名不存在,則反向代理到localhost 。這裏的break也是中止rewrite檢查 break; proxy_pass http://127.0.0.1; } if ($args ~ post=140){ #若是query string中包含"post=140",永久重定向到example.com rewrite ^ http://example.com/ permanent; }
nginx 配置案例參考
http { # 定義image日誌格式 log_format imagelog '[$time_local] ' $image_file ' ' $image_type ' ' $body_bytes_sent ' ' $status; # 開啓重寫日誌 rewrite_log on; server { root /home/www; location / { # 重寫規則信息 error_log logs/rewrite.log notice; # 注意這裏要用‘’單引號引發來,避免{} rewrite '^/images/([a-z]{2})/([a-z0-9]{5})/(.*)\.(png|jpg|gif)$' /data?file=$3.$4; # 注意不能在上面這條規則後面加上「last」參數,不然下面的set指令不會執行 set $image_file $3; set $image_type $4; } location /data { # 指定針對圖片的日誌格式,來分析圖片類型和大小 access_log logs/images.log mian; root /data/images; # 應用前面定義的變量。判斷首先文件在不在,不在再判斷目錄在不在,若是還不在就跳轉到最後一個url裏 try_files /$arg_file /image404.html; } location = /image404.html { # 圖片不存在返回特定的信息 return 404 "image not found\n"; } }