Nginx localhost路由匹配規則
URI 即統一標識資源符,通用的 URI 語法格式如下:
scheme:[//[user[:password]@]host[:port]][/path][?query][#fragment]
格式說明如下:
- 在 Nginx 的應用場景中,URL 與 URI 並無明確區別。URI 標准(RFC3986)中約定,URL 是 URI 的一個子集;
- scheme 是 URI 請求時遵守的協議,常見的有 HTTP、HTTPS、FTP;
- host[:port] 是主機名與端口號,HTTP 協議的默認端口是 80,HTTPS 協議的默認端口是 443;
- [/path] 是訪問路徑與訪問文件名;
- [?query] 是訪問參數,訪問參數以“?”開始作標識,由多個以“&”連接的 key=value 形式的字符串組成。
| 語法 | location [= | ~ | ~* | ^~ | @] URI { ... } |
|---|---|
| 位置 | server,location |
其中,[=||*|^~|@]部分稱為 location 修飾語(Modifier),修飾語定義了與 URI 的匹配方式。URI 為匹配項,可以是字符串或正則表達式。
URI 匹配規則
uri變量是待匹配的請求字符串,可以不包含正則表達式,也可以包含正則表達式,那么nginx服務器在搜索匹配location的時候,是先使用不包含正則表達式進行匹配,找到一個匹配度最高的一個,然后在通過包含正則表達式的進行匹配,如果能匹配到直接訪問,匹配不到,就使用剛才匹配度最高的那個location來處理請求。
無修飾語
| 修飾符 | |
|---|---|
| 解釋 | location 后沒有參數直接跟着 標准 URI,表示前綴匹配,代表跟請求中的 URI 從頭開始匹配。 |
server {
location /abc {
...
}
}
以下訪問:只要以前綴abc開始就可以匹配,?后的都是訪問參數
http://192.168.204.131/abc/def http://192.168.204.131/abc?p1=TOM http://192.168.204.131/abc/ http://192.168.204.131/abcdef...
修飾語 "="
| 修飾符 | = |
|---|---|
| 解釋 | 用於標准 URI 前,要求請求字符串與其精准匹配,成功則立即處理,nginx停止搜索其他匹配,Linux 系統下會區分大小寫,Windows 系統下則不會 |
server {
location =/abc {
...
}
}
以下訪問:只能完全匹配 abc; ?后的都是訪問參數
#可以匹配 http://192.168.204.131/abc http://192.168.204.131/abc?p1=TOM #匹配不到 http://192.168.204.131/abc/ http://192.168.204.131/abcdef http://192.168.204.131/abc/def
修飾語 "~ | ~*"
| 修飾符 | ~ | ~* |
|---|---|
| 解釋 | 用於正則 URI 前,表示 URI 包含正則表達式,~ 區分大小寫,~* 不區分大小寫 |
server {
location ~ ^/ABCD$ {
...
}
}
server {
location ~* ^/abcd$ {
...
}
}
以下訪問:
# ~ 匹配 http://192.168.204.131/ABCD http://192.168.204.131/ABCD?name=tom # ~ 不匹配 http://192.168.204.131/ABCD/ # ~* 匹配 http://192.168.204.131/aBcD http://192.168.204.131/abcd?p1=TOM # ~* 不匹配 http://192.168.204.131/abcd/
修飾語 "^~"
| 修飾符 | ^~ |
|---|---|
| 解釋 | 用於標准 URI 前,並要求一旦匹配到就會立即處理,不再去匹配其他的那些個正則 URI,一般用來匹配目錄;注意,這不是一個正則表達式匹配,它的目的是優先於正則表達式的匹配 |
server {
location ^~ /abc {
...
}
}
修飾語 "@"
| 修飾符 | @ |
|---|---|
| 解釋 | @ 定義一個命名的 location,@ 定義的locaiton名字一般用在內部定向,例如error_page, try_files命令中。它的功能類似於編程中的goto。 |
server {
location @jump_to_error_page {
default_type text/plain;
return 200 "not found ";
}
error_page 404 =200 @jump_to_error_page;
}
表示沒找頁面或資源,但是我正確返回了200,並通知沒找到。
匹配順序
| 優先級 | 修飾符 | 解釋 |
|---|---|---|
| 1 | location = | # 精准匹配 |
| 2 | location ^~ | # 帶參前綴匹配 |
| 3 | location ~ | # 正則匹配(區分大小寫) |
| 4 | location ~* | # 正則匹配(不區分大小寫) |
| 5 | location /a | # 普通前綴匹配,優先級低於帶參數前綴匹配 |
| 6 | location / | # 任何沒有匹配成功的,都會匹配這里處理 |
案例分析
案例1
location /doc {
return 701;
}
location ~* ^/document$ {
return 702;
}
curl -i localhost/document 702
按照上述的規則,顯然第二個正則匹配會有更高的優先級
案例2
location /document {
return 701;
}
location ~* ^/document$ {
return 702;
}
curl -i localhost/doucument 702
第二個匹配了正則表達式,優先級高於第一個普通前綴匹配
案例3
location ^~ /doc {
return 701;
}
location ~* /document {
return 702;
}
curl -i localhost/document 701
第一個前綴匹配 ^~ 命中以后不會再搜尋正則匹配,所以會第一個命中
案例4
location /docu {
return 701;
}
location /doc {
return 702;
}
location /my {
return 701;
}
location /myweb {
return 702;
}
curl -i localhost/document 701
curl -i localhost/doc 702
curl -i localhost/myweb 702
curl -i localhost /mywebm 702
前綴匹配下,返回最長匹配的 ,與 location 所在位置順序無關
curl -i localhost/myw 701
前綴匹配下,字符串沒達到最長匹配,返回短的 location;
案例 5
location ~* ^/doc[a-z]+ {
return 701;
}
location ~* ^/docu[a-z]+ {
return 702;
}
location ~* ^/myw[a-z]+ {
return 701;
}
location ~* ^/my[a-z]+ {
return 702;
}
curl -i localhost/document 701
curl -i localhost/myweb 701
可見正則匹配是使用文件中的順序,先匹配成功的返回。
curl -i localhost/myw 702
當完全匹配,就使用完全匹配 location;
location 實際使用建議
直接匹配網站根,通過域名訪問網站首頁比較頻繁,使用這個會加速處理
這里是直接轉發給后端應用服務器
location = / {
proxy_pass http://192.168.204.131:19901/index
}
第二個必選規則是處理靜態文件請求,這是 nginx 作為 http 服務器的強項,有兩種配置模式,目錄匹配或后綴匹配,任選其一或搭配使用:
location ^~ /static/ {
root /html/static/;
}
location ~* \.(gif|jpg|jpeg|png|css|js)$ {
root /html/res/;
}
第三個規則就是通用規則,用來轉發動態請求到后端應用服務器,非靜態文件請求就默認是動態請求;
location / {
proxy_pass http://192.168.204.131:19901/
}
