将NGINX
配置为Web
服务器是定义它处理哪些URL
以及如何处理这些URL
上资源的HTTP
请求的问题。在较低级别,配置定义了一组虚拟服务器,用于控制对特定域或 IP
地址的请求的处理。
HTTP
流量的每个虚拟服务器都定义了称为location
的特殊配置实例,这些实例控制特定 URI
集的处理。每个位置都定义了自己的方案,用于处理映射到此位置的请求所发生的情况。NGINX
提供了对此过程的完全控制。每个location
都可以代理请求或返回文件。此外,还可以修改 URI
,以便将请求重定向到另一个位置或虚拟服务器。此外,还可以返回特定的错误代码,并且可以配置特定页面以对应于每个错误代码。
NGINX
配置文件必须包含至少一个服务器指令才能定义虚拟服务器。当 NGINX
处理请求时,它首先选择将为请求提供服务的虚拟服务器。
虚拟服务器由 http
指令域中的server
指令定义,例如:
http {
server {
# Server configuration
}
}
可以在上下文中 http
添加多个指令以定义多个 server 虚拟服务器。
server
配置块通常包括一个 listen
指令,用于指定服务器侦听请求的 IP
地址和端口(或 Unix
域套接字和路径)。接受 IPv4
和 IPv6
地址;将 IPv6
地址括在方括号中。
以下示例显示了侦听 IP 地址 127.0.0.1 和端口 8080 的服务器的配置:
server {
listen 127.0.0.1:8080;
# Additional server configuration
}
如果省略端口,则使用标准端口。同样,如果省略某个地址,服务器将侦听所有地址。如果根本不包含该 listen
指令,则“标准”端口是,“默认”端口是 80/tcp 8000/tcp
,具体取决于超级用户权限。
如果有多个服务器与请求的 IP
地址和端口匹配,NGINX
会根据 server
块中的 server_name
指令测试请求 Host
的标头字段。参数 server_name
可以是完整(精确)名称、通配符或正则表达式。通配符是开头和/或结尾包含星号 ( * ) 的字符串;星号匹配任何字符序列。NGINX
将 Perl
语法用于正则表达式;在它们前面加上波浪号 ( ~ )。此示例说明了确切的名称。
server {
listen 80;
server_name example.org www.example.org;
#...
}
如果多个名称与 Host
标头匹配,NGINX
会通过按以下顺序搜索名称并使用找到的第一个匹配项来选择一个名称:
如果 Host
标头字段与服务器名称不匹配,NGINX
会将请求路由到请求到达的端口的默认服务器。默认服务器是 nginx.conf
文件中列出的第一个服务器,除非您在 listen
指令中包含 default_server
参数以显式指定默认服务器。
server {
listen 80 default_server;
#...
}
参考:
NGINX
可以根据请求 URI
将流量发送到不同的代理或提供不同的文件。这些块是使用放置在 server
指令中的 location
指令定义的。
例如,您可以定义三个 location
块来指示虚拟服务器将一些请求发送到一个代理服务器,将其他请求发送到另一个代理服务器,并通过从本地文件系统传送文件来处理其余请求。
NGINX
根据所有 location
指令的参数测试请求 URI
,并应用在匹配位置中定义的指令。在每个 location
块中,通常可以(除了少数例外)放置更多 location
指令,以进一步优化特定请求组的处理。
该 location
指令有两种类型的参数:前缀字符串(路径名)和正则表达式。要使请求 URI
与前缀字符串匹配,它必须以前缀字符串开头。
以下带有 pathname
参数的示例位置与以 /some/path/
开头的请求 URI
匹配,例如 /some/path/document.html
。(它与 /my-site/some/path
不匹配,因为 /some/path
不会出现在该 URI 的开头。
location /some/path/ {
#...
}
正则表达式前面有波浪号 ( ) 表示区分大小写匹配,或波浪号星号 ( ~ ~* ) 表示不区分大小写的匹配。以下示例匹配在任何位置包含字符串 .html
或 .htm
的 URI
。
location ~ \.html? {
#...
}
为了找到与 URI
最匹配的位置,NGINX
首先将 URI
与带有前缀字符串的位置进行比较。然后,它使用正则表达式搜索位置。
除非使用 ^~ 修饰符,否则正则表达式的优先级更高。在前缀字符串中,NGINX
选择最具体的字符串(即最长和最完整的字符串)。选择处理请求的位置的确切逻辑如下:
URI
。URI
。= 修饰符的典型用例是请求 /(正斜杠)。如果频繁请求 /,则指定 = / 为 location
指令的参数可加快处理速度,因为在第一次比较后停止对匹配项的搜索。
location = / {
#...
}
location
上下文可以包含定义如何解析请求的指令 - 提供静态文件或将请求传递给代理服务器。在以下示例中,将提供与第一个上下文匹配的请求来自 /data 目录的文件,并将与第二个 location
上下文匹配的请求传递到承载 www.example.com 域内容的代理服务器。
server {
location /images/ {
# 注意 / 不要加在前面,不然找不到文件目录
root data/;
}
location / {
proxy_pass http://www.example.com;
}
}
root
指令指定要在其中搜索要提供的静态文件的文件系统路径。与location
关联的请求 URI
将追加到路径中,以获取要提供的静态文件的全名。在上面的示例中,为了响应对 /images/example.png
的请求,NGINX
提供了文件 /data/images/example.png
。
proxy_pass
指令将请求传递到使用配置的 URL
访问的代理服务器。然后,来自代理服务器的响应将传递回客户端。在上面的示例中,所有 URI
不以 /images/ 开头的请求都将传递到代理服务器。
可以使用配置文件中的变量,让 NGINX
根据定义的情况以不同的方式处理请求。变量是在运行时计算的命名值,用作指令的参数。变量在其名称开头用 $
(美元) 符号表示。变量根据 NGINX
的状态定义信息,例如当前正在处理的请求的属性。
有许多预定义的变量,例如核心 HTTP
变量,您可以使用 set
、map
和 geo
指令定义自定义变量。大多数变量都是在运行时计算的,并包含与特定请求相关的信息。例如, $remote_addr
包含客户端 IP
地址并 $uri
保存当前 URI
值。
某些网站 URI
要求立即返回带有特定错误或重定向代码的响应,例如,当页面被临时或永久移动时。执行此操作的最简单方法是使用 return
指令。例如:
location /wrong/url {
return 404;
}
第一个 return
参数是响应代码。可选的第二个参数可以是重定向的 URL
(对于代码 301 、 、 302 303 和 307 ),也可以是要在响应正文中返回的文本。例如:
location /permanently/moved/url {
return 301 http://www.example.com/moved/here;
}
在请求处理期间,可以通过使用 rewrite
指令多次修改请求 URI
,该指令具有一个可选参数和两个必需参数。第一个(必需)参数是请求 URI
必须匹配的正则表达式。第二个参数是要替换匹配 URI
的 URI
。可选的第三个参数是一个标志,可以停止处理其他 rewrite
指令或发送重定向(code 301 或 302 )。例如:
location /users/ {
rewrite ^/users/(.*)$ /show?user=$1 break;
}
如此示例所示,第二个参数 users 捕获正则表达式的匹配。
您可以在 server
和 location
上下文中包含多个 rewrite
指令。NGINX
按照指令出现的顺序逐个执行指令。选择 server
上下文时,上下文中的 rewrite
指令将执行一次。
NGINX
处理完一组重写指令后,会根据新的 URI
选择一个 location
上下文。如果所选位置包含 rewrite
指令,则依次执行这些指令。如果 URI
与其中任何一个匹配,则在处理完所有定义的 rewrite
指令后开始搜索新位置。
下面的示例显示 rewrite
指令与 return
指令的组合。
server {
#...
rewrite ^(/download/.*)/media/(\w+)\.?.*$ $1/mp3/$2.mp3 last;
rewrite ^(/download/.*)/audio/(\w+)\.?.*$ $1/mp3/$2.ra last;
return 403;
#...
}
此示例配置区分两组 URI
。URI
(如 /download/some/media/file)更改为 /download/some/mp3/file.mp3。由于该 last
标志,后续指令(第二个 rewrite
和 return
指令)将被跳过,但 NGINX
继续处理请求,该请求现在具有不同的 URI
。同样,/download/some/audio/file 等 URI 将替换为 /download/some/mp3/file.ra。如果 URI
与任一 rewrite
指令都不匹配,NGINX
会将 403 错误代码返回给客户端。
有两个参数会中断指令的 rewrite
处理:
last
– 停止在当前 server
或 location
上下文中执行指令,但 NGINX
会搜索与重写的 URI
匹配的位置,并应用新位置中的任何 rewrite
rewrite
指令(这意味着 URI
可以再次更改)。break
– 与 break
指令一样,停止处理当前上下文中的 rewrite
指令,并取消对与新 URI
匹配的位置的搜索。新位置中的 rewrite
指令不会执行。有时,需要重写或更改 HTTP
响应中的内容,将一个字符串替换为另一个字符串。可以使用 sub_filter
指令来定义要应用的重写。该指令支持变量和替换链,使更复杂的更改成为可能。
例如,您可以更改引用代理以外的服务器的绝对链接:
location / {
sub_filter /blog/ /blog-staging/;
sub_filter_once off;
}
另一个示例将方案从 http:// 更改为 , https:// 并将 localhost
地址替换为请求标头字段中的主机名。sub_filter_once
指令告诉 NGINX
在一个位置内连续应用sub_filter
指令:
location / {
sub_filter 'href="http://127.0.0.1:8080/' 'href="https://$host/';
sub_filter 'img src="http://127.0.0.1:8080/' 'img src="https://$host/';
sub_filter_once on;
}
请注意,如果发生另一个 sub_filter
匹配项,则不会再次替换已使用 修改 sub_filter
的响应部分。
使用 error_page
指令,您可以将 NGINX
配置为返回自定义页面和错误代码,在响应中替换不同的错误代码,或将浏览器重定向到不同的 URI
。在以下示例中,该 error_page
指令指定要返回的页面 (/404.html) 以及 404 错误代码。
error_page 404 /404.html;
请注意,此指令并不意味着立即返回错误(指令 return
会这样做),而只是指定在错误发生时如何处理错误。错误代码可能来自代理服务器,也可能在 NGINX
处理期间发生(例如,当 `` 找NGINX不到客户端请求的文件时 404 出现的结果)。
在以下示例中,当 NGINX
找不到页面时,它会将代码替换为代码 301 404 ,并将客户端重定向到 http:/example.com/new/path.html。当客户端仍在尝试访问旧 URI 上的页面时,此配置非常有用。该 301 代码通知浏览器页面已永久移动,并且需要在返回时自动将旧地址替换为新地址。
location /old/path.html {
error_page 404 =301 http:/example.com/new/path.html;
}
以下配置是在找不到文件时将请求传递到后端的示例。由于 error_page
指令中的等号后未指定状态代码,因此对客户端的响应具有代理服务器返回的状态代码(不一定 404 )。
server {
...
location /images/ {
# Set the root directory to search for the file
root /data/www;
# Disable logging of errors related to file existence
open_file_cache_errors off;
# Make an internal redirect if the file is not found
error_page 404 = /fetch$uri;
}
location /fetch/ {
proxy_pass http://backend/;
}
}
该 error_page
指令指示 NGINX
在找不到文件时进行内部重定向。 error_page
指令的最后一个参数中的 $uri
变量保存当前请求的 URI
,该 URI
在重定向中传递。
例如,如果未找到 /images/some/file,则将其替换为 /fetch/images/some/file,并开始对位置进行新的搜索。因此,请求最终进入第二个 location
上下文,并被代理给 http://backend/。
open_file_cache_errors
指令可防止在找不到文件时写入错误消息。这里没有必要这样做,因为丢失的文件会得到正确处理。