nginx
如果你正在运行Nginx web服务器,对你来说,明白location指令怎么工作的,是很重要的。
对于进来的URL,Nginx利用location指令决定基于前缀或正则来应用哪些配置。
比如,当一个以*.gif或*.png或任何其他图片文件名扩展,它应该从哪些目录来提供图片文件。
在这个教程,我们将通过例子解释如下内容:
- 默认
Location指令运行 - 改变默认的
NginxRootLocation
(即DocumentRoot) - 使用
Location自定义404页面 - 使用
Location自定义多个50x服务器错误 - 从一个自定义的
Location
提供你的网站图片 - 使用
=(等于号)Location修饰符提取匹配 - 使用
~(波浪号)进行大小写正则表达式匹配 - 使用
~*(波浪-星号)进行不区分大小写正则表达式匹配 ^~最好非正则匹配(尖角-波浪号)NginxLocation关联的错误消息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遇到一个HTTP404错误码时,通过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








网友评论