location
語法
location [ = | ~ | ~* | ^~ ] /uri/ { … }
模式 | 含義 |
---|---|
location = /uri | = 表示精確匹配萝喘,只有完全匹配上才能生效 |
location ^~ /uri | ^~ 開頭對URL路徑進行前綴匹配蹬碧,并且在正則之前送朱。 |
location ~ pattern | 開頭表示區(qū)分大小寫的正則匹配 |
location ~* pattern | 開頭表示不區(qū)分大小寫的正則匹配 |
location /uri | 不帶任何修飾符坝咐,也表示前綴匹配,但是在正則匹配之后 |
location / | 通用匹配卜录,任何未匹配到其它location的請求都會匹配到鹅士,相當于switch中的default |
-
=
開頭表示精確匹配 -
^~
開頭表示uri以某個常規(guī)字符串開頭,不是正則匹配 -
~
開頭表示區(qū)分大小寫的正則匹配; -
~*
開頭表示不區(qū)分大小寫的正則匹配 -
/
通用匹配, 如果沒有其它匹配,任何請求都會匹配到
匹配的優(yōu)先級
首先精確匹配 =
其次前綴匹配 ^~
其次是按文件中順序的正則匹配
然后匹配不帶任何修飾的前綴匹配轰胁。
最后是交給 / 通用匹配
當有匹配成功時候谒主,停止匹配,按當前匹配規(guī)則處理請求
location = / {
# 精確匹配 / 赃阀,主機名后面不能帶任何字符串
[ configuration A ]
}
location / {
# 因為所有的地址都以 / 開頭霎肯,所以這條規(guī)則將匹配到所有請求
# 但是正則和最長字符串會優(yōu)先匹配
[ configuration B ]
}
location /documents/ {
# 匹配任何以 /documents/ 開頭的地址,匹配符合以后榛斯,還要繼續(xù)往下搜索
# 只有后面的正則表達式?jīng)]有匹配到時观游,這一條才會采用這一條
[ configuration C ]
}
location ~ /documents/Abc {
# 匹配任何以 /documents/Abc 開頭的地址,匹配符合以后肖抱,還要繼續(xù)往下搜索
# 只有后面的正則表達式?jīng)]有匹配到時备典,這一條才會采用這一條
[ configuration CC ]
}
location ^~ /images/ {
# 匹配任何以 /images/ 開頭的地址,匹配符合以后意述,停止往下搜索正則提佣,采用這一條。
[ configuration D ]
}
location ~* \.(gif|jpg|jpeg)$ {
# 匹配所有以 gif,jpg或jpeg 結(jié)尾的請求
# 然而荤崇,所有請求 /images/ 下的圖片會被 config D 處理拌屏,因為 ^~ 到達不了這一條正則
[ configuration E ]
}
location /images/ {
# 字符匹配到 /images/,繼續(xù)往下术荤,會發(fā)現(xiàn) ^~ 存在
[ configuration F ]
}
location /images/abc {
# 最長字符匹配到 /images/abc倚喂,繼續(xù)往下,會發(fā)現(xiàn) ^~ 存在
# F與G的放置順序是沒有關(guān)系的
[ configuration G ]
}
location ~ /images/abc/ {
# 只有去掉 config D 才有效:先最長匹配 config G 開頭的地址,繼續(xù)往下搜索端圈,匹配到這一條正則焦读,采用
[ configuration H ]
}
location ~* /js/.*/\.js
Rewrite規(guī)則
rewrite功能就是,使用nginx提供的全局變量或自己設置的變量舱权,結(jié)合正則表達式和標志位實現(xiàn)url重寫以及重定向矗晃。
rewrite只能放在server{},location{},if{}中,并且只能對域名后邊的除去傳遞的參數(shù)外的字符串起作用宴倍,例如 http://seanlook.com/a/we/index.php?id=1&u=str 只對/a/we/index.php重寫张症。
語法rewrite regex replacement [flag]
;
比如:
location ~ ^/guonei/product/ {
rewrite ^/guonei/product/c_([0-9]+)_([0-9]+)\.html /zhuanti/gn_detail_wap/?c=$1&productId=$2 break;
proxy_set_header Host kaoyan.xxxxx.com;
proxy_pass https://kaoyan.xxxxx.com;
}
如果相對域名或參數(shù)字符串起作用,可以使用全局變量匹配鸵贬,也可以使用proxy_pass反向代理俗他。
表明看rewrite和location功能有點像,都能實現(xiàn)跳轉(zhuǎn)阔逼,主要區(qū)別在于rewrite是在同一域名內(nèi)更改獲取資源的路徑兆衅,而location是對一類路徑做控制訪問或反向代理,可以proxy_pass到其他機器颜价。很多情況下rewrite也會寫在location里涯保,它們的執(zhí)行順序是:
執(zhí)行server塊的rewrite指令
執(zhí)行l(wèi)ocation匹配
執(zhí)行選定的location中的rewrite指令
如果其中某步URI被重寫,則重新循環(huán)執(zhí)行1-3周伦,直到找到真實存在的文件夕春;循環(huán)超過10次,則返回500 Internal Server Error錯誤专挪。
flag標志位
last
: 相當于Apache的[L]標記及志,表示完成rewrite
break
: 停止執(zhí)行當前虛擬主機的后續(xù)rewrite指令集
redirect
: 返回302臨時重定向,地址欄會顯示跳轉(zhuǎn)后的地址
permanent
: 返回301永久重定向寨腔,地址欄會顯示跳轉(zhuǎn)后的地址
因為301和302不能簡單的只返回狀態(tài)碼速侈,還必須有重定向的URL,這就是return指令無法返回301,302的原因了迫卢。這里 last 和 break 區(qū)別有點難以理解:
last一般寫在server和if中倚搬,而break一般使用在location中
last不終止重寫后的url匹配,即新的url會再從server走一遍匹配流程乾蛤,而break終止重寫后的匹配
break和last都能組織繼續(xù)執(zhí)行后面的rewrite指令
if指令與全局變量
if判斷指令
語法為if(condition){...}
每界,對給定的條件condition進行判斷。如果為真家卖,大括號內(nèi)的rewrite指令將被執(zhí)行眨层,if條件(conditon)可以是如下任何內(nèi)容:
當表達式只是一個變量時,如果值為空或任何以0開頭的字符串都會當做false
直接比較變量和內(nèi)容時上荡,使用=
或!=
~
正則表達式匹配趴樱,~*
不區(qū)分大小寫的匹配,!~
區(qū)分大小寫的不匹配
-f
和!-f
用來判斷是否存在文件
-d
和!-d
用來判斷是否存在目錄
-e
和!-e
用來判斷是否存在文件或目錄
-x
和!-x
用來判斷文件是否可執(zhí)行
if ($http_user_agent ~ MSIE) {
rewrite ^(.*)$ /msie/$1 break;
} //如果UA包含"MSIE",rewrite請求到/msid/目錄下
if ($http_cookie ~* "id=([^;]+)(?:;|$)") {
set $id $1;
} //如果cookie匹配正則叁征,設置變量$id等于正則引用部分
if ($request_method = POST) {
return 405;
} //如果提交方法為POST纳账,則返回狀態(tài)405(Method not allowed)。return不能返回301,302
if ($slow) {
limit_rate 10k;
} //限速航揉,$slow可以通過 set 指令設置
if (!-f $request_filename){
break;
proxy_pass http://127.0.0.1;
} //如果請求的文件名不存在塞祈,則反向代理到localhost 。這里的break也是停止rewrite檢查
if ($args ~ post=140){
rewrite ^ http://example.com/ permanent;
} //如果query string中包含"post=140"帅涂,永久重定向到example.com
location ~* \.(gif|jpg|png|swf|flv)$ {
valid_referers none blocked www.jefflei.com www.leizhenfang.com;
if ($invalid_referer) {
return 404;
} //防盜鏈
}
全局變量
下面是可以用作if判斷的全局變量
-
$args
: #這個變量等于請求行中的參數(shù),同$query_string -
$content_length
: 請求頭中的Content-length字段尤蛮。 -
$content_type
: 請求頭中的Content-Type字段媳友。 -
$document_root
: 當前請求在root指令中指定的值。 -
$host
: 請求主機頭字段产捞,否則為服務器名稱醇锚。 -
$http_user_agent
: 客戶端agent信息 -
$http_cookie
: 客戶端cookie信息 -
$limit_rate
: 這個變量可以限制連接速率。 -
$request_method
: 客戶端請求的動作坯临,通常為GET或POST焊唬。 -
$remote_addr
: 客戶端的IP地址。 -
$remote_port
: 客戶端的端口看靠。 -
$remote_user
: 已經(jīng)經(jīng)過Auth Basic Module驗證的用戶名赶促。 -
$request_filename
: 當前請求的文件路徑,由root或alias指令與URI請求生成挟炬。 -
$scheme
: HTTP方法(如http鸥滨,https)。 -
$server_protocol
: 請求使用的協(xié)議谤祖,通常是HTTP/1.0或HTTP/1.1婿滓。 -
$server_addr
: 服務器地址,在完成一次系統(tǒng)調(diào)用后可以確定這個值粥喜。 -
$server_name
: 服務器名稱凸主。 -
$server_port
: 請求到達服務器的端口號。 -
$request_uri
: 包含請求參數(shù)的原始URI额湘,不包含主機名卿吐,如:”/foo/bar.php?arg=baz”。 -
$uri
: 不帶請求參數(shù)的當前URI缩挑,$uri不包含主機名但两,如”/foo/bar.html”。 -
$document_uri
: 與$uri相同供置。
例:`http://localhost:88/test1/test2/test.php`
$host:localhost
$server_port:88
$request_uri:[http://localhost:88/test1/test2/test.php](http://localhost:88/test1/test2/test.php)
$document_uri:/test1/test2/test.php
$document_root:/var/www/html
$request_filename:/var/www/html/test1/test2/test.php
常用正則
-
.
: 匹配除換行符以外的任意字符 -
?
: 重復0次或1次 -
+
: 重復1次或更多次 -
*
: 重復0次或更多次 -
\d
:匹配數(shù)字 -
^
: 匹配字符串的開始 -
$
: 匹配字符串的介紹 -
{n}
: 重復n次 -
{n,}
: 重復n次或更多次 -
[c]
: 匹配單個字符c -
[a-z]
: 匹配a-z小寫字母的任意一個
小括號()
之間匹配的內(nèi)容谨湘,可以在后面通過$1
來引用,$2
表示的是前面第二個()
里的內(nèi)容。正則里面容易讓人困惑的是\
轉(zhuǎn)義特殊字符紧阔。
rewrite實例
例1:
http {
# 定義image日志格式
log_format imagelog '[$time_local] ' $image_file ' ' $image_type ' ' $body_bytes_sent ' ' $status;
# 開啟重寫日志
rewrite_log on;
server {
root /home/www;
location / {
# 重寫規(guī)則信息
error_log logs/rewrite.log notice;
# 注意這里要用‘’單引號引起來坊罢,避免{}
rewrite '^/images/([a-z]{2})/([a-z0-9]{5})/(.*)\.(png|jpg|gif)$' /data?file=$3.$4;
# 注意不能在上面這條規(guī)則后面加上“l(fā)ast”參數(shù),否則下面的set指令不會執(zhí)行
set $image_file $3;
set $image_type $4;
}
location /data {
# 指定針對圖片的日志格式擅耽,來分析圖片類型和大小
access_log logs/images.log mian;
root /data/images;
# 應用前面定義的變量活孩。判斷首先文件在不在,不在再判斷目錄在不在乖仇,如果還不在就跳轉(zhuǎn)到最后一個url里
try_files /$arg_file /image404.html;
}
location = /image404.html {
# 圖片不存在返回特定的信息
return 404 "image not found\n";
}
}
對形如/images/ef/uh7b3/test.png
的請求憾儒,重寫到/data?file=test.png
,于是匹配到location /data
乃沙,先看/data/images/test.png
文件存不存在起趾,如果存在則正常響應,如果不存在則重寫tryfiles到新的image404 location警儒,直接返回404狀態(tài)碼训裆。
例2:
rewrite ^/images/(.*)_(\d+)x(\d+)\.(png|jpg|gif)$ /resizer/$1.$4?width=$2&height=$3? last;
對形如/images/bla_500x400.jpg
的文件請求,重寫到/resizer/bla.jpg?width=500&height=400
地址蜀铲,并會繼續(xù)嘗試匹配location边琉。
參考: