以下是 nginx 配置文件中 location 指令的语法。
location [modifier] match {
}
在上面的语法中:
- modifier 是可选的
- match 定义了 URL 中应该匹配的内容来执行这个特定位置块中提到的配置。
- 当没有 modifier 时,匹配就作为传入 URL 的前缀字符串 如果我们在修饰符中使用 ~ 或 ~* ,则匹配可以是正则表达式。
- location 上下文是“服务器”。因此,您将在 server 中看到它,如下所示。
例如:
server {
listen 80;
server_name thegeekstuff.com
location / {
root /var/www/html;
index index.html index.htm;
}
..
..
}
您可以根据需要为您的网站设置任意数量的位置指令。
如果您不熟悉 Nginx,可以按照如何在 Linux 上从源代码安装和配置 Nginx 中的说明进行安装
1. 默认Location指令设置
如果您使用默认配置安装了 Nginx,您可以在 default.conf 文件中查看您当前的位置指令值,如下所示。
主要配置文件为:/etc/nginx/nginx.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 文件定义了以下两个位置指令
- / 默认位置
- /50x.html 所有服务器错误
2. 更改默认的 Nginx Root Location(即 DocumentRoot)
以下示例显示了如何更改 Nginx 网络服务器的默认 DocumentRoot。
以下内容将从您将在“location /”下的根目录中定义的目录中为您的 Nginx 服务器提供所有文件。
例如,以下内容将从 /var/www/html 目录而不是默认的 nginx 根位置提供 geekstuff.com/index.html 文件。
# 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。
但是在大多数情况下,如果您只是重新加载配置,而不是重新启动它就足够了,如下所示。
# service nginx reload
Reloading nginx: [ OK ]
3. 自定义 404 页面
使用 location 指令,您还可以配置当 nginx 遇到 HTTP 404 错误代码时应提供的文件。即找不到文件。
为此,请将以下几行添加到您的 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 页面。
- 然后位置目录说这个 /404.html 文件应该从 /var/www/html/errors 目录提供。
- 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>
4. 使用位置定义多个自定义 50x 服务器错误
默认情况下,您会在 default.conf 文件中看到类似以下内容。
在这个例子中,我修改了 50x.html 文件的位置并创建了一个自定义页面。
这里要注意的一件重要事情是,您可以将多个 HTTP 错误代码重定向到一个文件。如此处所示,任何服务器端错误代码(包括 500、502、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>
5. 从自定义位置提供您的网站图片
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,如如何将 Nginx 设置为 Apache 的负载均衡器或 HTTP/HTTPS 的 Tomcat 中所述
6. 使用 =(等号)位置修饰符的精确匹配
当您想要匹配确切的请求 URI 时,请使用 =(等号)作为修饰符。
要理解这一点,首先让我们使用以下不带等号的简单配置。
位置/数据库{
根/数据;
...
}
在上面,它将匹配以下 URL。以下所有操作都将起作用。
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 /db {
root /data;
...
}
在上面,它只会匹配以下 EXACT URL。没有别的办法了。
- URL/db – 会起作用。
- URL/db/index.html – 不起作用。
- URL/db/connect/index.html – 不起作用。
重要提示:另外,在上面的例子中,根值不会被兑现。这是因为 /db 将使用之前定义的“/”位置的根。因此,当您转到 URL/db 时,它将真正从 /var/www/html/db/ 提供 index.html 文件,而不是像您预期的那样从 /data/db/ 提供。
因此,当您将 URL 称为 thegeekstuff.com/db 时,上面带有 =(等号)的内容将提供以下文件
7. 使用 ~(波浪号)区分大小写的正则表达式匹配
当您想使用正则表达式匹配(而不是前缀匹配)时,您应该使用 ~(波浪号)。
使用 ~ 将执行区分大小写的匹配。
以下是使用 ~ 位置修饰符匹配图像 URL 的实际示例。
location ~ .(png|gif|ico|jpg|jpeg)$ {
}
在上面:
- ~ 用于区分大小写的正则表达式匹配修饰符
- ( ) – 此正则表达式中的所有值都将被视为 URL 中的关键字
- | 这是 OR 运算符。即会考虑 URL 中的 png、gif、ico、jpg 或 jpeg 关键字。
- $ 在末尾表示指定的关键字应该在 URL 的末尾。
- 基本上,整个正则表达式适用于任何图像 URL。即任何以图像文件结尾的 URL。
假设我们在图像目录中有以下文件:
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 网站)并对其进行处理,请参考此处的一些位置示例:如何在 Apache 和 Nginx 中为 PHP 添加自定义文件扩展名
8. 不区分大小写的正则表达式匹配使用 ~*(波浪号-星号)
这与上面的示例类似,但是这将执行不区分大小写的正则表达式匹配。
location ~* .(png|gif|ico|jpg|jpe?g)$ {
root /custom;
}
在这种情况下:
- URL/img/dog.gif – 这将起作用,因为我们的服务器上有 dog.gif。
- URL/img/CAT.GIF – 这也可以工作,因为这将被视为不区分大小写,并且即使 URL 具有大写的 CAT.GIF,nginx 也会从服务器提供 cat.git
9. ^~ 最佳非正则表达式匹配
使用此修饰符时,匹配的 URL 将使用此配置。基本上,此配置将用作前缀匹配,但即使可用,也不会执行任何进一步的正则表达式匹配。
location ^~ /img/ {
}
10. Nginx Location 相关错误信息
以下是一些与位置相关的错误消息,如果 location 指令中有问题,您将在重新启动 Nginx 时收到这些错误消息。
如果您有多个具有相同前缀匹配的位置指令,您将收到以下“重复位置”错误消息:
# service nginx start
Starting nginx: nginx: [emerg] duplicate location "/" in /etc/nginx/conf.d/default.conf:45 [FAILED]
如果您在错误的上下文中使用“位置”。即在服务器外部,那么您将收到以下错误消息:
# 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 允许的位置修饰符(例如:=)。在以下代码段中,我们使用 $ 作为 Nginx 不允许的位置修饰符。
location $ /ab {
root /var/www/html1;
index index.html index.htm;
}
在这种情况下,您将收到以下无效的位置修饰符错误消息,如下所示。
# 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
11. 位置修饰符总结
为了正确看待事情,以下列出了上面讨论的大部分位置示例:
以下 = 用于精确匹配。例如:thegeekstuff.com/
location = / {
}
以下不带任何修饰符是用于 / 后跟任何东西的。例如:thegeekstuff.com/contact.html
location / {
}
以下是针对 /db 的。例如:thegeekstuff.com/db/index.html
位置 /db/ {
} 以下是没有 Reg-Ex 的最佳前缀匹配。例如:thegeekstuff.com/images/logo.gif
location ^~ /images/ {
}
以下是正则表达式匹配。例如:thegeekstuff.com/db/mysql.jpg
location ~* .(png|gif|ico|jpg|jpeg)$ {
}
12. 使用@(At 符号)定义自定义命名位置
您还可以在 location 指令中使用 @(at 符号),如下例所示。
对此,需要注意以下几点:
- 使用@ 定义命名位置
- 此位置配置为请求重定向。这不用于常规请求处理。
- 您不能嵌套 @location 指令
下面是一个例子:
location / {
try_files $uri $uri/ @custom;
}
location @custom {
rewrite ^/(.+)$ /index.php?_route_=$1 last;
}
原文: https://www.thegeekstuff.com/2017/05/nginx-location-examples/