
如果你正在运行Nginx
web
服务器,对你来说,明白location
指令怎么工作的,是很重要的。
对于进来的URL,Nginx
利用location
指令决定基于前缀或正则来应用哪些配置。
比如,当一个以*.gif
或*.png
或任何其他图片文件名扩展,它应该从哪些目录来提供图片文件。
在这个教程,我们将通过例子解释如下内容:
- 默认
Location
指令运行 - 改变默认的
Nginx
RootLocation
(即DocumentRoot
) - 使用
Location
自定义404页面 - 使用
Location
自定义多个50x
服务器错误 - 从一个自定义的
Location
提供你的网站图片 - 使用
=
(等于号)Location
修饰符提取匹配 - 使用
~
(波浪号)进行大小写正则表达式匹配 - 使用
~*
(波浪-星号)进行不区分大小写正则表达式匹配 ^~
最好非正则匹配(尖角-波浪号)Nginx
Location
关联的错误消息Location
修饰符概括- 使用
@
自定义命名Location
Nginx
Location
匹配处理顺序和逻辑
接下来是nginx
配置文件location
指令的语法
syntax:
location [modifier] match {
}
在上面的语法中:
-
Modifier
是可选的 -
Match
定义在URL
里什么应该被匹配到来执行配置,那些配置在这个特定的location
块中被提到 - 当没有
modifier
时,match
对进来的URL
仅仅执行前缀匹配 - 如果在
modifier
使用~
或~*
,则match
将是一个正则表达式
location
块的上下文是server
。所以,你将在server
块中看见如下的这些内容。
比如:
server {
listen 80;
server_name thegeekstuff.com
location / {
root /var/www/html;
index index.html index.htm;
}
..
..
}
你可以为您的网站设置任意数量的location
指令。
如果你是 Nginx
新手,你能通过 How to Install and Configure Nginx from Source on Linux 解释的那样,来安装它。
默认Location
指令运行
如果你通过默认配置已安装Nginx
,你能看到你的当前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`指令
-
/
针对默认的location
-
/50x.html
针对所有服务器错误
改变默认的Nginx
Root Location
(即DocumentRoot
)
接下来的例子展示,针对你的Nginx
服务器,你怎么改变默认的DocumentRoot
。
在location /
下,通过在root
里面定义的目录,Nginx
服务器将提供所有的文件。
比如,如下将提供thegeekstuff.com/index.html
文件,使用/var/www/html
目录,代替nginx
默认的root位置。
# vi /etc/nginx/conf.d/default.conf
location / {
root /var/www/html;
index index.html index.htm;
}
在/var/www/html
下,为了这次测试,我们创建示例文件。
# 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
配置文件,你应该使用systemctl
或service
命令来重启nginx
。
但是,大多数场景,代替重启它,如果你仅仅通过如下的reload
配置,那是足够好的。
# service nginx reload
Reloading nginx: [ OK ]
使用Location
自定义404页面
当nginx
遇到一个HTTP
404错误码时,通过location
指令,你也能配置应提供的文件,即,File Not Found
为了达到此目的,在你的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
表示,当404
错误被捕获,它应该展示/404.html
页面。 -
location
目录表示,从/var/www/html/errors 目录中,提供这个/404.html
文件 - 紧跟
location
指令后的修饰符=
表示,针对提供的配置,URL
/404.html
不得不精确地匹配。基本上,它表示这个配置仅针对404
错误码才是有效的
自从我们已自定义这个目录位置,创建错误目录和如下所示的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
服务器错误
默认,你将看到像如下的已经在default.conf
文件中的一些事情。
在这个例子中,我们修改50x.html
文件的位置,并且创建一个自定义页面。
这里需要注意的一件重要事情是,你能跳转多个HTTP
错误码到单个文件。如下所示,任何服务器端的错误码(包括500
,501
,503
或504
)将跳转到叫50x.html
的一个错误文件。
在这个例子中,我们创建了这个 50x.html
文件,并且将它放到错误目录里。
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /var/www/html/errors;
}
下一步,在我们自定义的错误目录里,创建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
提供你的网站图片
针对location
指令,另外一个典型的应用是指定location
目录,你想要提供所有你网站的图片文件的目录。
在如下的例子中,任何时候,你调用一个包含/img
紧跟着一个图片文件名的url
,它将在/custom/images
目录里寻找这个图片文件。
location /img/ {
root /custom/images;
}
针对这个例子,在这个目录中,我们有如下的图片文件:
# ls -1 /custom/images/img/
dog.gif
cat.gif
fish.png
parrot.jpg
..
所以,当你调用thegeekstuff.com/img/cat.gif
,它将从上面的目录中提供cat.gif
如果你对负债均衡感兴趣的话,你应该在location
指令里使用proxy_pass
,它在这里 How to Setup Nginx as loadbalancer for Apache or Tomcat for HTTP/HTTPS被解释。
使用=
(等于号)Location
修饰符提取匹配
当你想要匹配精准的请求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
文件
但是,当我们添加=
(等于号)location
修饰符,如下所示,上述行为将发生改变。
location = /db {
root /data;
}
如上所述,它将仅仅匹配如下的EXACT URL
。其他不将起作用。
- URL/db – 起作用
- URL/db/index.html – 不起作用
- URL/db/connect/index.html – 不起作用
重要提示:此外,在上面的例子中的示例中,root
值不起作用。这是因为/db
将使用更早定义的root
/
位置。所以,当你得到URL/db
时,它将已经提供 index.html
文件,从/var/www/html/db/
,而不是从你期望的/data/db/
。
所以,当你调用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
另外,请注意,当 Nginx
匹配具有 =
修饰符的特定location
指令时,将不会寻找任何进一步的location
指令。
一个流行的配置是针对你已经存在的Apache/PHP
网站,安装Nginx
作为前端。为此,你应该按照此处的说明使用反向代理:How to Setup Nginx Reverse Proxy to Apache/PHP on Linux
使用~
(波浪号)进行大小写正则表达式匹配
当你想要使用正则表达式匹配(代替前缀匹配)时,你应该使用~
(波浪号)。
使用~
将执行区分大小写匹配。
接下来是一个特殊的例子,为了匹配图片URLs,使用~
location
修饰符。
location ~ .(png|gif|ico|jpg|jpeg)$ {
}
在上面的例子中:
-
~
用于区分大小写的正则表达式匹配修饰符 - ( ) – 此正则表达式中的所有值都将被视为 URL 中的关键字
- |这是 OR 运算符。即,将考虑 URL 中的 png、gif、ico、jpg 或 jpeg 关键字
- 末尾的 $ 表示指定的关键字应位于 URL 的末尾
- 基本上,整个正则表达式适用于任何图像 URL。即任何以图像文件结尾的 URL
假设我们在 images 目录中有以下文件:
dog.gif
cat.gif
fish.png
parrot.jpg
..
在上面的例子中:
- URL/img/dog.gif – 这将工作,因为在我们的服务器上,我们有dog.gif
- URL/img/CAT.GIF – 这将不工作,因为我们没有大写的
CAT.GIF
(在服务器端,我们仅有小写的cat.gif
)。因为我们使用~
,它将做区分大小写匹配,不将提供这个大写的CAT.GIF
文件
此外,除了指定两个关键字 jpg 和 jpeg,您还可以使"jpe?g"将它们组合起来,如下所示
location ~ .(png|gif|ico|jpe?g)$ {
}
如果您想匹配 URL 中的 php
关键字(对于 php
网站)并对其进行处理,请参阅此处的一些 Location
示例:How to Add Custom File Extension for PHP in Apache and Nginx
使用~*
(波浪-星号)进行不区分大小写正则表达式匹配
这类似于上面的示例,但是这将执行不区分大小写的正则表达式匹配。
location ~* .(png|gif|ico|jpg|jpe?g)$ {
root /custom;
}
在上面的例子中:
- URL/img/dog.gif – 这将工作,因为在我们的服务器上,我们有dog.gif
- URL/img/CAT.GIF – 这也将工作,因为这将被视为不区分大小写,
nginx
将从服务器提供cat.gif
,尽管URL
有大写的CAT.GIF
^~
最好非正则匹配(尖角-波浪号)
使用此修饰符时,匹配的 URL 将使用此配置。基本上,此配置将用作前缀匹配,但即使有可用的,这也不会执行任何进一步的正则表达式匹配。
location ^~ /img/ {
}
Nginx
Location
关联的错误消息
以下是一些与location
相关的错误消息,如果 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
修饰符概括
为了正确看待事情,下面列出了上面讨论的大多数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/ {
}
以下是正则表达式匹配。例如:thegeekstuff.com/db/mysql.jpg
location ~* .(png|gif|ico|jpg|jpeg)$ {
}
使用@
自定义命名 Location
你还可以在 location
指令中使用 @(at 符号),如下例所示。
关于这一点,需要注意以下几点:
- 使用
@
定义命名location
- 此
location
配置为请求重定向。这不用于常规请求处理。 - 你不能嵌套
@
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
匹配处理顺序和逻辑
以下是关于location
匹配顺序和逻辑需要考虑的几件事:
- 首先,即使在任何
location
匹配发生之前,传入的URI
也会被规范化。例如,首先它将解码 URL 中的%XX
值 - 它还会解析
URL
中适当的相对路径组件,如果URL
中有多个斜杠/
,它会将它们压缩为单个斜杠等。只有在URL
的初始规范化之后,location
匹配才会发挥作用 - 当没有
location
修饰符时,它只会被视为要在URL
中匹配的前缀字符串 -
Nginx
将首先检查使用前缀字符串定义的匹配location
- 如果 URL 有多个
location
前缀字符串匹配,那么Nginx
将使用最长匹配的前缀location
- 在前缀匹配之后,
nginx
将按照它们在nginx
配置文件中定义的顺序检查正则表达式location
匹配 - 因此,在配置文件中定义正则表达式匹配的顺序很重要。
nginx
匹配正则表达式location
配置的那一刻,它不会再查找任何内容。因此,在配置顶部使用重要的关键正则表达式location
匹配 - 如果没有找到正则表达式匹配
location
,那么Nginx
将使用之前匹配的前缀location
配置
原文链接 13 Nginx Location Directive Examples including Regular Expression Modifiers
网友评论