如果你正在運行Nginx
web
服務(wù)器,對你來說序愚,明白location
指令怎么工作的,是很重要的叔营。
對于進(jìn)來的URL,Nginx
利用location
指令決定基于前綴或正則來應(yīng)用哪些配置所宰。
比如绒尊,當(dāng)一個以*.gif
或*.png
或任何其他圖片文件名擴(kuò)展,它應(yīng)該從哪些目錄來提供圖片文件仔粥。
在這個教程婴谱,我們將通過例子解釋如下內(nèi)容:
- 默認(rèn)
Location
指令運行 - 改變默認(rèn)的
Nginx
RootLocation
(即DocumentRoot
) - 使用
Location
自定義404頁面 - 使用
Location
自定義多個50x
服務(wù)器錯誤 - 從一個自定義的
Location
提供你的網(wǎng)站圖片 - 使用
=
(等于號)Location
修飾符提取匹配 - 使用
~
(波浪號)進(jìn)行大小寫正則表達(dá)式匹配 - 使用
~*
(波浪-星號)進(jìn)行不區(qū)分大小寫正則表達(dá)式匹配 ^~
最好非正則匹配(尖角-波浪號)Nginx
Location
關(guān)聯(lián)的錯誤消息Location
修飾符概括- 使用
@
自定義命名Location
Nginx
Location
匹配處理順序和邏輯
接下來是nginx
配置文件location
指令的語法
syntax:
location [modifier] match {
}
在上面的語法中:
-
Modifier
是可選的 -
Match
定義在URL
里什么應(yīng)該被匹配到來執(zhí)行配置,那些配置在這個特定的location
塊中被提到 - 當(dāng)沒有
modifier
時躯泰,match
對進(jìn)來的URL
僅僅執(zhí)行前綴匹配 - 如果在
modifier
使用~
或~*
谭羔,則match
將是一個正則表達(dá)式
location
塊的上下文是server
。所以麦向,你將在server
塊中看見如下的這些內(nèi)容口糕。
比如:
server {
listen 80;
server_name thegeekstuff.com
location / {
root /var/www/html;
index index.html index.htm;
}
..
..
}
你可以為您的網(wǎng)站設(shè)置任意數(shù)量的location
指令。
如果你是 Nginx
新手磕蛇,你能通過 How to Install and Configure Nginx from Source on Linux 解釋的那樣,來安裝它十办。
默認(rèn)Location
指令運行
如果你通過默認(rèn)配置已安裝Nginx
秀撇,你能看到你的當(dāng)前location
指令值,在如下的default.conf
里向族。
主要的配置文件是/etc/nginx/nginx.conf
呵燕。
但是,server
和location
指令在default.conf
里件相,default.conf
位于/etc/nginx/conf.d/default.conf
再扭,default.conf
如下所示。
# vi /etc/nginx/conf.d/default.conf
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
location = /50x.html {
root /usr/share/nginx/html;
}
default.conf文件定義了如下的兩個
location`指令
-
/
針對默認(rèn)的location
-
/50x.html
針對所有服務(wù)器錯誤
改變默認(rèn)的Nginx
Root Location
(即DocumentRoot
)
接下來的例子展示夜矗,針對你的Nginx
服務(wù)器泛范,你怎么改變默認(rèn)的DocumentRoot
。
在location /
下紊撕,通過在root
里面定義的目錄罢荡,Nginx
服務(wù)器將提供所有的文件。
比如对扶,如下將提供thegeekstuff.com/index.html
文件区赵,使用/var/www/html
目錄峭梳,代替nginx
默認(rèn)的root位置页徐。
# vi /etc/nginx/conf.d/default.conf
location / {
root /var/www/html;
index index.html index.htm;
}
在/var/www/html
下,為了這次測試媳危,我們創(chuàng)建示例文件络凿。
# cat /var/www/html/index.html
<html>
<head>
<title>Hello World</title>
</head>
<body>
<h1>Hello World! - New Nginx Root Location</h1>
</body>
</html>
注意:任何時候骡送,你修改了nginx
配置文件昂羡,你應(yīng)該使用systemctl
或service
命令來重啟nginx
。
但是各谚,大多數(shù)場景紧憾,代替重啟它,如果你僅僅通過如下的reload
配置昌渤,那是足夠好的赴穗。
# service nginx reload
Reloading nginx: [ OK ]
使用Location
自定義404頁面
當(dāng)nginx
遇到一個HTTP
404錯誤碼時,通過location
指令膀息,你也能配置應(yīng)提供的文件般眉,即,File Not Found
為了達(dá)到此目的潜支,在你的default.conf
文件里甸赃,添加如下行。
# vi /etc/nginx/conf.d/default.conf
error_page 404 /404.html;
location = /404.html {
root /var/www/html/errors;
}
在上面的例子中:
-
error_page
–使用此指令來定義你想要捕獲什么類型的錯誤冗酿。我們在這里捕獲的是404
錯誤埠对。/404.html
表示,當(dāng)404
錯誤被捕獲裁替,它應(yīng)該展示/404.html
頁面项玛。 -
location
目錄表示,從/var/www/html/errors 目錄中弱判,提供這個/404.html
文件 - 緊跟
location
指令后的修飾符=
表示襟沮,針對提供的配置,URL
/404.html
不得不精確地匹配昌腰】基本上,它表示這個配置僅針對404
錯誤碼才是有效的
自從我們已自定義這個目錄位置遭商,創(chuàng)建錯誤目錄和如下所示的404.html
文件
# mkdir -p /var/www/html/errors
# cat 404.html
<html>
<head>
<title>404 - Where did it go?</title>
</head>
<body>
<h1>File Not Found: Don't worry. We'll find it for you. Please contact us.</h1>
</body>
</html>
使用Location
自定義多個50x
服務(wù)器錯誤
默認(rèn)固灵,你將看到像如下的已經(jīng)在default.conf
文件中的一些事情。
在這個例子中劫流,我們修改50x.html
文件的位置怎虫,并且創(chuàng)建一個自定義頁面。
這里需要注意的一件重要事情是困介,你能跳轉(zhuǎn)多個HTTP
錯誤碼到單個文件大审。如下所示,任何服務(wù)器端的錯誤碼(包括500
座哩,501
徒扶,503
或504
)將跳轉(zhuǎn)到叫50x.html
的一個錯誤文件。
在這個例子中根穷,我們創(chuàng)建了這個 50x.html
文件姜骡,并且將它放到錯誤目錄里导坟。
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /var/www/html/errors;
}
下一步,在我們自定義的錯誤目錄里圈澈,創(chuàng)建50x.html
文件
# cd /var/www/html/errors;
# vi 50x.html
<html>
<head>
<title>50x - Server Error</title>
</head>
<body>
<h1>Something went wrong on the server side. Please contact our server admin.</h2>
</body>
</html>
從一個自定義的Location
提供你的網(wǎng)站圖片
針對location
指令惫周,另外一個典型的應(yīng)用是指定location
目錄,你想要提供所有你網(wǎng)站的圖片文件的目錄康栈。
在如下的例子中递递,任何時候,你調(diào)用一個包含/img
緊跟著一個圖片文件名的url
啥么,它將在/custom/images
目錄里尋找這個圖片文件登舞。
location /img/ {
root /custom/images;
}
針對這個例子,在這個目錄中悬荣,我們有如下的圖片文件:
# ls -1 /custom/images/img/
dog.gif
cat.gif
fish.png
parrot.jpg
..
所以菠秒,當(dāng)你調(diào)用thegeekstuff.com/img/cat.gif
,它將從上面的目錄中提供cat.gif
如果你對負(fù)債均衡感興趣的話氯迂,你應(yīng)該在location
指令里使用proxy_pass
践叠,它在這里 How to Setup Nginx as loadbalancer for Apache or Tomcat for HTTP/HTTPS被解釋。
使用=
(等于號)Location
修飾符提取匹配
當(dāng)你想要匹配精準(zhǔn)的請求URI
時嚼蚀,使用=
(等于號)作為修飾符酵熙。
為了理解這個,首先驰坊,讓我們用接下來簡單的沒有等于號的配置。
location /db {
root /data;
...
}
如上所述哮独,它將匹配如下的URI
拳芙。如下的所有都將起作用。
- URL/db – 將在
/data/db
下尋找index.html
文件 - URL/db/index.html – 將在
/data/db
下尋找index.html
文件 - URL/db/connect/index.html – 將在
/data/db/connect
下尋找index.html
文件
但是皮璧,當(dāng)我們添加=
(等于號)location
修飾符舟扎,如下所示,上述行為將發(fā)生改變悴务。
location = /db {
root /data;
}
如上所述睹限,它將僅僅匹配如下的EXACT URL
。其他不將起作用讯檐。
- URL/db – 起作用
- URL/db/index.html – 不起作用
- URL/db/connect/index.html – 不起作用
重要提示:此外羡疗,在上面的例子中的示例中,root
值不起作用别洪。這是因為/db
將使用更早定義的root
/
位置叨恨。所以,當(dāng)你得到URL/db
時挖垛,它將已經(jīng)提供 index.html
文件痒钝,從/var/www/html/db/
秉颗,而不是從你期望的/data/db/
。
所以送矩,當(dāng)你調(diào)用URL
蚕甥,比如thegeekstuff.com/db
,帶有=
(等于號)的修飾符栋荸,將提供如下的文件菇怀。
# ls -l /var/www/html/db/index.html
-rw-r--r--. 1 root root 13 May 8 17:28 /var/www/html/db/index.html
另外,請注意蒸其,當(dāng) Nginx
匹配具有 =
修飾符的特定location
指令時敏释,將不會尋找任何進(jìn)一步的location
指令。
一個流行的配置是針對你已經(jīng)存在的Apache/PHP
網(wǎng)站摸袁,安裝Nginx
作為前端钥顽。為此,你應(yīng)該按照此處的說明使用反向代理:How to Setup Nginx Reverse Proxy to Apache/PHP on Linux
使用~
(波浪號)進(jìn)行大小寫正則表達(dá)式匹配
當(dāng)你想要使用正則表達(dá)式匹配(代替前綴匹配)時靠汁,你應(yīng)該使用~
(波浪號)蜂大。
使用~
將執(zhí)行區(qū)分大小寫匹配。
接下來是一個特殊的例子蝶怔,為了匹配圖片URLs奶浦,使用~
location
修飾符。
location ~ .(png|gif|ico|jpg|jpeg)$ {
}
在上面的例子中:
-
~
用于區(qū)分大小寫的正則表達(dá)式匹配修飾符 - ( ) – 此正則表達(dá)式中的所有值都將被視為 URL 中的關(guān)鍵字
- |這是 OR 運算符踢星。即澳叉,將考慮 URL 中的 png、gif沐悦、ico成洗、jpg 或 jpeg 關(guān)鍵字
- 末尾的 $ 表示指定的關(guān)鍵字應(yīng)位于 URL 的末尾
- 基本上,整個正則表達(dá)式適用于任何圖像 URL藏否。即任何以圖像文件結(jié)尾的 URL
假設(shè)我們在 images 目錄中有以下文件:
dog.gif
cat.gif
fish.png
parrot.jpg
..
在上面的例子中:
- URL/img/dog.gif – 這將工作瓶殃,因為在我們的服務(wù)器上,我們有dog.gif
- URL/img/CAT.GIF – 這將不工作副签,因為我們沒有大寫的
CAT.GIF
(在服務(wù)器端遥椿,我們僅有小寫的cat.gif
)。因為我們使用~
淆储,它將做區(qū)分大小寫匹配冠场,不將提供這個大寫的CAT.GIF
文件
此外,除了指定兩個關(guān)鍵字 jpg 和 jpeg本砰,您還可以使"jpe?g"將它們組合起來慈鸠,如下所示
location ~ .(png|gif|ico|jpe?g)$ {
}
如果您想匹配 URL 中的 php
關(guān)鍵字(對于 php
網(wǎng)站)并對其進(jìn)行處理,請參閱此處的一些 Location
示例:How to Add Custom File Extension for PHP in Apache and Nginx
使用~*
(波浪-星號)進(jìn)行不區(qū)分大小寫正則表達(dá)式匹配
這類似于上面的示例,但是這將執(zhí)行不區(qū)分大小寫的正則表達(dá)式匹配青团。
location ~* .(png|gif|ico|jpg|jpe?g)$ {
root /custom;
}
在上面的例子中:
- URL/img/dog.gif – 這將工作譬巫,因為在我們的服務(wù)器上,我們有dog.gif
- URL/img/CAT.GIF – 這也將工作督笆,因為這將被視為不區(qū)分大小寫芦昔,
nginx
將從服務(wù)器提供cat.gif
,盡管URL
有大寫的CAT.GIF
^~
最好非正則匹配(尖角-波浪號)
使用此修飾符時娃肿,匹配的 URL 將使用此配置咕缎。基本上料扰,此配置將用作前綴匹配凭豪,但即使有可用的,這也不會執(zhí)行任何進(jìn)一步的正則表達(dá)式匹配晒杈。
location ^~ /img/ {
}
Nginx
Location
關(guān)聯(lián)的錯誤消息
以下是一些與location
相關(guān)的錯誤消息嫂伞,如果 location
指令有問題,您會在重新啟動 Nginx
時收到這些錯誤消息拯钻。
如果您有多個具有相同前綴匹配的location
指令帖努,您將收到以下"duplicate location"錯誤消息:
# service nginx start
Starting nginx: nginx: [emerg] duplicate location "/" in /etc/nginx/conf.d/default.conf:45 [FAILED]
如果你在錯誤的上下文中使用location
。即在server
之外粪般,那么您將收到以下錯誤消息:
# service nginx restart
nginx: [emerg] "location" directive is not allowed here in /etc/nginx/nginx.conf:34
nginx: configuration file /etc/nginx/nginx.conf test failed
你只能使用 nginx
允許的location
修飾符(例如 =
)拼余。在下面的代碼片段中,我們使用 $
作為 Nginx
不允許的location
修飾符亩歹。
location $ /ab {
root /var/www/html1;
index index.html index.htm;
}
在這種情況下匙监,你將收到以下無效的location
修飾符錯誤消息,如下所示小作。
# service nginx restart
nginx: [emerg] invalid location modifier "$" in /etc/nginx/conf.d/default.conf:17
nginx: configuration file /etc/nginx/nginx.conf test failed
Location
修飾符概括
為了正確看待事情亭姥,下面列出了上面討論的大多數(shù)location
示例:
以下 =
用于完全匹配。例如:thegeekstuff.com/
location = / {
}
以下沒有任何修飾符是 for /
后跟任何東西躲惰。例如:thegeekstuff.com/contact.html
location / {
}
以下是針對 /db
的。例如:thegeekstuff.com/db/index.html
location /db/ {
}
以下是沒有 Reg-Ex 的最佳前綴匹配变抽。例如:thegeekstuff.com/images/logo.gif
location ^~ /images/ {
}
以下是正則表達(dá)式匹配础拨。例如:thegeekstuff.com/db/mysql.jpg
location ~* .(png|gif|ico|jpg|jpeg)$ {
}
使用@
自定義命名 Location
你還可以在 location
指令中使用 @(at 符號),如下例所示绍载。
關(guān)于這一點诡宗,需要注意以下幾點:
- 使用
@
定義命名location
- 此
location
配置為請求重定向。這不用于常規(guī)請求處理击儡。 - 你不能嵌套
@
location
指令
下面是一個例子:
location / {
try_files $uri $uri/ @custom;
}
location @custom {
rewrite ^/(.+)$ /index.php?_route_=$1 last;
}
在上面的例子中的例子中:
首先塔沃,
@custom
本身可以在任何其他location
塊中定義。如上例所示阳谍,這是在第一個location
塊中使用try_files
定義的蛀柴。接下來螃概,
location @custom
指的是之前在任何其他location
塊中定義的@custom
命名location
。此自定義命名location
用于上面的第二個location
塊鸽疾。請注意吊洼,你可以隨意稱呼它而不是
@custom
。例如:@database
制肮、@myapp
冒窍、@complexredirect
、@misc
豺鼻、@thegeekstuff
Nginx
Location
匹配處理順序和邏輯
以下是關(guān)于location
匹配順序和邏輯需要考慮的幾件事:
- 首先综液,即使在任何
location
匹配發(fā)生之前,傳入的URI
也會被規(guī)范化儒飒。例如谬莹,首先它將解碼 URL 中的%XX
值 - 它還會解析
URL
中適當(dāng)?shù)南鄬β窂浇M件,如果URL
中有多個斜杠/
约素,它會將它們壓縮為單個斜杠等届良。只有在URL
的初始規(guī)范化之后,location
匹配才會發(fā)揮作用 - 當(dāng)沒有
location
修飾符時圣猎,它只會被視為要在URL
中匹配的前綴字符串 -
Nginx
將首先檢查使用前綴字符串定義的匹配location
- 如果 URL 有多個
location
前綴字符串匹配士葫,那么Nginx
將使用最長匹配的前綴location
- 在前綴匹配之后,
nginx
將按照它們在nginx
配置文件中定義的順序檢查正則表達(dá)式location
匹配 - 因此送悔,在配置文件中定義正則表達(dá)式匹配的順序很重要慢显。
nginx
匹配正則表達(dá)式location
配置的那一刻,它不會再查找任何內(nèi)容欠啤。因此荚藻,在配置頂部使用重要的關(guān)鍵正則表達(dá)式location
匹配 - 如果沒有找到正則表達(dá)式匹配
location
,那么Nginx
將使用之前匹配的前綴location
配置
原文鏈接 13 Nginx Location Directive Examples including Regular Expression Modifiers