1)location匹配的是nginx的哪個變量?
$request_uri
2)location的匹配種類有哪些?
格式:location [ 空格 | = | ~ | ~* | !~ | !~* | @ ] /uri/ {}
解釋:
= 表示精確匹配,如果找到,立即停止搜索并立即處理此請求。
~ 表示執(zhí)行一個正則匹配,區(qū)分大小寫匹配
~* 表示執(zhí)行一個正則匹配,不區(qū)分大小寫匹配
!~ 區(qū)分大小寫不匹配
!~* 不區(qū)分大小寫不匹配
^~ 即表示只匹配普通字符(空格)。使用前綴匹配,^表示“非”,即不查詢正則表達式。如果匹配成功,則不再匹配其他location。
@ 指定一個命名的location,一般只用于內(nèi)部重定向請求。例如 error_page, try_files
/ 表示通用匹配,任何請求都會匹配到
對應(yīng)示例說明:
1)=
server {
server_name wangshibo.com;
location = /abcd {
[…]
}
}
匹配情況:
http://wangshibo.com/abcd # 正好完全匹配
http://wangshibo.com/ABCD # 如果運行 Nginx server 的系統(tǒng)本身對大小寫不敏感,比如 Windows ,那么也匹配
http://wangshibo.com/abcd?param1?m2 # 忽略查詢串參數(shù)(query string arguments),這里就是 /abcd 后面的 ?param1?m2
http://wangshibo.com/abcd/ # 不匹配,因為末尾存在反斜杠(trailing slash),Nginx 不認為這種情況是完全匹配
http://wangshibo.com/abcde # 不匹配,因為不是完全匹配
2)(None)
可以不寫 location modifier ,Nginx 仍然能去匹配 pattern 。這種情況下,匹配那些以指定的 patern 開頭的 URI,注意這里的 URI 只能是普通字符串,不能使用正則表達式。
server {
server_name website.com;
location /abcd {
[…]
}
}
匹配情況:
http://wangshibo.com/abcd # 正好完全匹配
http://wangshibo.com/ABCD # 如果運行 Nginx server 的系統(tǒng)本身對大小寫不敏感,比如 Windows ,那么也匹配
http://wangshibo.com/abcd?param1?m2 # 忽略查詢串參數(shù)(query string arguments),這里就是 /abcd 后面的 ?param1?m2
http://wangshibo.com/abcd/ # 末尾存在反斜杠(trailing slash)也屬于匹配范圍內(nèi)
http://wangshibo.com/abcde # 仍然匹配,因為 URI 是以 pattern 開頭的
3)~
這個 location modifier 對大小寫敏感,且 pattern 須是正則表達式
server {
server_name wangshibo.com;
location ~ ^/abcd$ {
[…]
}
}
匹配情況:
http://wangshibo.com/abcd # 完全匹配
http://wangshibo.com/ABCD # 不匹配,~ 對大小寫是敏感的
http://wangshibo.com/abcd?param1?m2 # 忽略查詢串參數(shù)(query string arguments),這里就是 /abcd 后面的 ?param1?m2
http://wangshibo.com/abcd/ # 不匹配,因為末尾存在反斜杠(trailing slash),并不匹配正則表達式 ^/abcd$
http://wangshibo.com/abcde # 不匹配正則表達式 ^/abcd$
注意:對于一些對大小寫不敏感的系統(tǒng),比如 Windows ,~ 和 ~* 都是不起作用的,這主要是操作系統(tǒng)的原因。
4)~*
與 ~ 類似,但這個 location modifier 不區(qū)分大小寫,pattern 須是正則表達式
server {
server_name website.com;
location ~* ^/abcd$ {
[…]
}
}
匹配情況:
http://wangshibo.com/abcd # 完全匹配
http://wangshibo.com/ABCD # 匹配,這就是它不區(qū)分大小寫的特性
http://wangshibo.com/abcd?param1?m2 # 忽略查詢串參數(shù)(query string arguments),這里就是 /abcd 后面的 ?param1?m2
http://wangshibo.com/abcd/ # 不匹配,因為末尾存在反斜杠(trailing slash),并不匹配正則表達式 ^/abcd$
http://wangshibo.com/abcde # 不匹配正則表達式 ^/abcd$
5)^~
匹配情況類似 2. (None) 的情況,以指定匹配模式開頭的 URI 被匹配,不同的是,一旦匹配成功,那么 Nginx 就停止去尋找其他的 Location 塊進行匹配了(與 Location 匹配順序有關(guān))
6. @
用于定義一個 Location塊,且該塊不能被外部Client 所訪問,只能被Nginx內(nèi)部配置指令所訪問,比如try_files 或 error_page
location @resize {
rewrite ^/(.*)/cache/(.*)?(.*)$ /resize.php?dir=$1&path=$2$3;
rewrite ^/(.*)/orgi/cert/(.*)?(.*)$ /pass/resize?dir=$1&type=cert&path=$2$3&is_orgi=true;
rewrite ^/(.*)/orgi/card/(.*)?(.*)$ /pass/resize?dir=$1&type=card&path=$2$3&is_orgi=true;
rewrite ^/(.*)/orgi/(.*)/(.*)?(.*)$ /pass/resize?dir=$1&type=$2&path=$3$4&is_orgi=true;
include fastcgi_params;
}
如下示例:
#通用匹配
location / {
root /var/www/web/;
autoindex on;
autoindex_exact_size off;
autoindex_localtime on;
access_log /var/www/log/nginx/access.log;
error_log /var/www/log/nginx/error.log;
}
#正則匹配
#proxy the php scripts to php-fpm
location ~ \.php(.*)$ {
root /var/www/web/;
fastcgi_pass 127.0.0.1:9000;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_read_timeout 300;
}
#精確匹配
location = /hello.php {
root /var/www/web/;
rewrite ^(.*)$ http://www.wangshibo.com redirect;
}
產(chǎn)生的效果如下:
訪問根目錄/,匹配到location /
訪問除hello.php之外的其它php程序,匹配到location ~ \.php$,并且用php5-fpm去運行
訪問hello.php,匹配到location = /hello.php,訪問被重定向到http://www.wangshibo.com
3)location搜索優(yōu)先級順序如何?
精確匹配 > 字符串匹配( 長 > 短 [ 注: ^~ 匹配則停止匹配 ]) > 正則匹配( 上 > 下 )
==========================================================================================================================
在nginx的location和配置中l(wèi)ocation的順序沒有太大關(guān)系。正location表達式的類型有關(guān)。
相同類型的表達式,字符串長的會優(yōu)先匹配。
優(yōu)先級排列(下面是在location匹配的內(nèi)容是一樣長度的path內(nèi)容的情況下,比如匹配的path都是images的情況下):
1)等號類型(=)的精確匹配優(yōu)先級最高,精確匹配只能命中一個。一旦匹配成功,則不再查找其他匹配項。
2)^~類型表達式,即字符串匹配,使用匹配最長的最為匹配結(jié)果。一旦匹配成功,則不再查找其他匹配項。
3)正則表達式類型(~ ~*)的優(yōu)先級次之。如果有多個location的正則能匹配的話,則使用正則表達式最長的那個。
4)常規(guī)字符串匹配類型。按前綴匹配。
特別注意:
字符串匹配優(yōu)先搜索,但是只是記錄下最長的匹配 (如果 ^~ 是最長的匹配,則會直接命中,停止搜索正則),然后繼續(xù)搜索正則匹配,
如果有正則匹配,則命中正則匹配,如果沒有正則匹配,則命中最長的字符串匹配.
--------------------------------------------------------------------------------------
結(jié)論:
去分和不區(qū)分大小寫的正則匹配優(yōu)先級相同,以先后順序來決定匹配哪一個.
=的優(yōu)先級比~高
=的優(yōu)先級比 ^~高
^~的優(yōu)先級比~高
^~優(yōu)先匹配的是從根開始的匹配
不加的優(yōu)先級比~低
~與*~正則匹配的優(yōu)先級按先后次序來決定的
--------------------------------------------------------------------------------------
即nginx匹配的優(yōu)先級順序為:
[不加] < [~/~*] < [^~] < [=]
--------------------------------------------------------------------------------------
下面通過示例進行驗證:
1)先來測試下區(qū)分大小寫和不區(qū)分大小寫的優(yōu)先級.如下:
location ~ /5b.txt {
return 501;
}
location ~* /5b.txt {
return 504;
}
測試結(jié)果為:
http://192.168.1.80/5b.txt ------------501
http://192.168.1.80/5B.txt ------------504
將順序反下,將~*放前面
location ~* /5b.txt {
return 501;
}
location ~ /5b.txt {
return 504;
}
測試結(jié)果為:
http://192.168.1.80/5b.txt ------------501
http://192.168.1.80/5B.txt ------------501
結(jié)論: 去分和不區(qū)分大小寫的正則匹配優(yōu)先級相同,以先后順序來決定匹配哪一個.
2)再來比較=與~的優(yōu)先級
location = /5b.txt {
return 502;
}
location ~ /5b.txt {
return 504;
}
測試結(jié)果為:
http://192.168.1.80/5b.txt -------------502
結(jié)論:=的優(yōu)先級比~高
3)再來比較下 ^~ 與 ~的優(yōu)先級
location ~ /5b.txt {
return 502;
}
location ^~ /5b.txt {
return 504;
}
測試結(jié)果為:
http://192.168.1.80/5b.txt --------------504
結(jié)論:^~的優(yōu)先級比~高
4)再測試 ^~ 與 = 的優(yōu)先級
location ^~ /5b.txt {
return 502;
}
location = /5b.txt {
return 504;
}
測試結(jié)果:
http://192.168.1.80/5b.txt --------------504
結(jié)論:=的優(yōu)先級比 ^~高
5)再來測試^~同級之間的優(yōu)先級
location ^~ 5b.txt {
return 502;
}
location ^~ /5b.txt/ {
return 504;
}
測試結(jié)果:
http://192.168.1.80/5b.txt --------------504
結(jié)論 :^~優(yōu)先匹配的是從根開始的匹配
6)再來看空格(即什么都不加)與~的優(yōu)先級比較
location /5b.txt {
return 502;
}
location ~ /5b.txt {
return 504;
}
測試結(jié)果為:
http://192.168.1.80/5b.txt --------------504
結(jié)論:空格的優(yōu)先級比~低
優(yōu)先級排序為:
空格(即不加)
~與*~正則匹配的優(yōu)先級按先后次序來決定的
^~同級之間的匹配是按照根目錄順序來的
------------------------------------------------------------------------------------------
再來看看下面的例子 (這里為了方面測試內(nèi)容輸出,使用了echo-nginx-module):
1)精確匹配,即“=”
location = /images/test.png {
echo 'config1';
}
location /images/test.png {
echo 'config2';
}
location \/images\/test\.png$ {
echo 'config3';
}
如果此時請求 http://127.0.0.1/images/test.png 輸出的內(nèi)容是config1, 毋容置疑,精確匹配優(yōu)先級最高!
2)精確匹配的特殊情況
location = / {
index index.html;
}
location / {
echo 'config2';
}
此時輸入http://127.0.0.1 輸出的內(nèi)容是config2, 怎么精確匹配的優(yōu)先級不靈了呢?
是這樣的,精確匹配還是起作用了,請求目錄(非具體文件),nginx會將請求內(nèi)部定向到index文件,
既此時真正的請求是http://127.0.0.1/index.html, 這是config2則被命中!
所以精確匹配不要用來匹配/
3)字符串搜索與正則搜索
location /images/test.png {
echo 'config1';
}
location ^~ /images/ {
echo 'config2';
}
location ~ \/images\/test\.png$ {
echo 'config3';
}
location ~ \/images\/ {
echo 'config4';
}
如果此時請求http://127.0.0.1/images/test.png 輸出的內(nèi)容是config3,正則命中。
(雖然config1為最長匹配的字符串,此時只做記錄,后面還要搜索正則匹配,則config3正則匹配命中),
仔細觀察可以發(fā)現(xiàn)config4也被匹配成功了,但是正則的匹配順序是按照location的定義順序匹配的,所以config3命中(注意示例中帶了"\"的正則的轉(zhuǎn)義符).
4)字符串匹配優(yōu)先級的提升( ^~ )
location /images/ {
echo 'config1';
}
location ^~ /images/test.png {
echo 'config2';
}
location ~ /images/test\.png$ {
echo 'config3';
}
location ~ \/images\/ {
echo 'config4';
}
如果此時請求 http://127.0.0.1/images/test.png 輸出的內(nèi)容是config2, 首部匹配命中。
(因為字符串匹配是優(yōu)先搜索的,此時發(fā)現(xiàn)config2 為最長的字符串匹配且為^~匹配方式,所以停止搜索正則,直接命中!)
所以這里的 ^~ 符號比較特殊,就是為了提高字符串匹配的優(yōu)先級,優(yōu)先于正則匹配.
------------------------------------------------------------------
/ 通用匹配,任何請求都會匹配到。
多個location配置的情況下,需要遵循:
首先匹配=
其次匹配^~
再其次按照配置文件的順序進行正則匹配、
最后是交給/進行通用匹配
注意:當有匹配成功時,立刻停止匹配,按照當前匹配規(guī)則處理請求
看看下面匹配規(guī)則:
#規(guī)則A
location = / {
}
#規(guī)則B
location = /login {
}
#規(guī)則C
location ^~ /static/ {
}
#規(guī)則D
location ~ \.(gif|jpg|png|js|css)$ {
}
#規(guī)則E
location ~* \.png$ {
}
#規(guī)則F
location !~ \.xhtml$ {
}
#規(guī)則G
location !~* \.xhtml$ {
}
#規(guī)則H
location / {
}
那么產(chǎn)生的效果如下:
1)訪問根目錄/, 比如http://localhost/ 將匹配規(guī)則A
2)訪問 http://localhost/login 將匹配規(guī)則B,http://localhost/register 則匹配規(guī)則H
3)訪問 http://localhost/static/a.html 將匹配規(guī)則C
4)訪問 http://localhost/a.gif, http://localhost/b.jpg 將匹配規(guī)則D和規(guī)則E,但是規(guī)則D順序優(yōu)先,規(guī)則E不起作用,而 http://localhost/static/c.png 則優(yōu)先匹配到規(guī)則C
5)訪問 http://localhost/a.PNG 則匹配規(guī)則E,而不會匹配規(guī)則D,因為規(guī)則E不區(qū)分大小寫。
6)訪問 http://localhost/a.xhtml 不會匹配規(guī)則F和規(guī)則G,http://localhost/a.XHTML不會匹配規(guī)則G,因為不區(qū)分大小寫。規(guī)則F,規(guī)則G屬于排除法,符合匹配規(guī)則但是不會匹配到,所以想想看實際應(yīng)用中哪里會用到。
7)訪問 http://localhost/category/id/1111 則最終匹配到規(guī)則H,因為以上規(guī)則都不匹配,這個時候應(yīng)該是nginx轉(zhuǎn)發(fā)請求給后端應(yīng)用服務(wù)器,比如FastCGI(php),tomcat(jsp),nginx作為方向代理服務(wù)器存在。
注意:在實際使用中,至少清楚下面匹配規(guī)則
1)直接匹配網(wǎng)站根,通過域名訪問網(wǎng)站首頁比較頻繁,使用這個會加速處理,官網(wǎng)如是說。
2)這里是直接轉(zhuǎn)發(fā)給后端應(yīng)用服務(wù)器了,也可以是一個靜態(tài)首頁
第一個必選規(guī)則:
location = / {
proxy_pass http://tomcat:8080/index
}
第二個必選規(guī)則是處理靜態(tài)文件請求,這是nginx作為http服務(wù)器的強項
有兩種配置模式,目錄匹配或后綴匹配,任選其一或搭配使用
location ^~ /static/ {
root /webroot/static/;
}
location ~* \.(gif|jpg|jpeg|png|css|js|ico)$ {
root /webroot/res/;
}
第三個規(guī)則就是通用規(guī)則,用來轉(zhuǎn)發(fā)動態(tài)請求到后端應(yīng)用服務(wù)器
非靜態(tài)文件請求就默認是動態(tài)請求,自己根據(jù)實際把握
畢竟目前的一些框架的流行,帶.php,.jsp后綴的情況很少了
location / {
proxy_pass http://tomcat:8080/
看看下面幾個設(shè)置
# 重寫跳轉(zhuǎn)
rewrite "^/conference/([^/]+)$" /con_detail.php?con_title=$1 last;
rewrite "^/conference/([^/]+)/$" /con_detail.php?con_title=$1 last;
#屏蔽爬蟲
if ($http_user_agent ~* "qihoobot|Baiduspider|Googlebot|Googlebot-Mobile|Googlebot-Image|Mediapartners-Google|Adsbot-Google|Feedfetcher-Google|Yahoo! Slurp|Yahoo! Slurp China|YoudaoBot|Sosospider|Sogou spider|Sogou web spider|MSNBot|ia_archiver|Tomato Bot")
{
return 403;
}
#favicon.ico不用打日志
location = /favicon.ico {
log_not_found off;
access_log off;
}
#不允許訪問隱藏文件
location ~ /\. {
deny all;
access_log off;
log_not_found off;
}
#訪問圖片,flash文件等不用打日志
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$ {
expires 7d; #文件返回的過期時間是7天
access_log off;
}
#訪問js和css文件不用打日志
location ~ .*\.(js|css)?$ {
expires 1d; #文件返回的過期時間是1天
access_log off;
}
#設(shè)置php-cgi
location ~ [^/]\.php(/|$) {
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
#攔截不存在的php頁面請求
if (!-f $document_root$fastcgi_script_name) {
return 404;
}
}
轉(zhuǎn)載自: https://www.cnblogs.com/kevingrace/