概述
在 Nginx 的配置文件中,由于涉及到 URI 路径或者文件系统中的目录时,都会有结尾处 "/" 问题,这里来专门说明。
location 上下文中的结尾斜杠
location 上下文的结尾斜杠比较好理解,举例来说:
-
location /doc { ... }- 普通前缀匹配(无修饰符),由于 URL 路径没有末尾斜杠,则可以匹配以 "/doc" 开头的任意 URL,如:/doc/index.html/docs/index.html/document/a.html- ...
-
location /docs/ { ... }- 普通前缀匹配(无修饰符),由于 URL 路径有末尾斜杠,则可以匹配以 "/docs/" 开头的任意 URL,如:/docs/index.html/docs/a.png/docs/sub/b.js- ...
目录别名中的结尾斜杠
若您使用了 Nginx 的别名功能,则需要:
- 要实现该功能,您需要在 location 上下文中使用
alias指令 - 若
alias指令后面的指令参数是一个目录,则强烈建议结尾处带有 "/" ,表明这是一个目录,如alias /test/; - 若 location 上下文匹配的是目录资源,则 URL 路径在结尾处也应该带有 "/",如
location /images/ { ... } - 若使用了目录别名功能,则在对应的 location 上下文中通常都会使用
index指令定义一个或多个索引文件,若索引文件不存在,Nginx 默认会提示 "403" 错误,除非开启了目录浏览(目录列表)功能
正确配置:location 上下文的 URL 路径与别名指令的指令参数都带有末尾 "/"
...
events {
...
}
...
http {
...
server {
...
location / {
# 这里 root 指令的指令参数通常都建议在结尾处带上 "/"
root /html/games/;
index index.html index.htm;
}
# location 中 URI 的结尾必须带上 "/",因为在此 location 上下文中使用了 alias 指令
location /images/ {
# 使用了 alias 指令,指令参数的结尾必须带上 "/"
# 浏览器请求 http://192.168.100.20/images/dogs.jpg 时,实际请求的是文件系统中的 /var/www/attachment/dogs.jpg
alias /var/www/attachment/;
autoindex off;
}
}
}
特殊情况:在 Nginx 中也允许 location 的 URL 路径与别名指令的指令参数末尾都不带 "/",但是不建议这样配置,容易出现路径错误问题。都不带末尾 "/" 仅出现在文件别名这种非常特殊的情况,如下所示
...
events {
...
}
...
http {
...
server {
...
location / {
root /html/games/;
index index.html index.htm;
}
# 精准前缀匹配
location = /favicon.ico {
alias /var/www/static/my-favicon.ico;
}
}
}
alias 指令的指令参数的结尾 "/" 与 location 上下文中的 URL 路径结尾 "/" 强烈建议成对出现反向代理中的结尾斜杠
proxy_pass 指令用来设置后端服务器的协议(http 协议或 https 协议)和地址(IP 地址或域名),语法为 proxy_pass URL;
情况 A :proxy_pass 指令的指令参数不带结尾斜杠
若配置文件的内容是类似这样的:
...
events {
...
}
...
http {
...
upstream backend1 {
server 192.168.100.30 max_fails=3 fail_timeout=60s;
server 192.168.100.35 max_fails=3 fail_timeout=60s;
server 192.168.100.40 max_fails=3 fail_timeout=60s;
}
...
server {
listen 192.168.100.20:80;
server_name my-tests.com www.my-tests.com;
return 301 https://www.my-tests.com$request_uri;
}
server {
listen 192.168.100.20:443 ssl http2 backlog=8000 reuseport;
server_name www.my-tests.com;
# SSL/TLS 证书相关的配置
...
# 其他相关的配置
...
# location 上下文的 URL 结尾处带了 "/"
location /images/ {
# 指定上游服务器,这里的 URL 在结尾处没有带 "/"
proxy_pass http://backend1;
...
}
}
}
此处,Nginx 代理服务器会保留 location 匹配的 URL 路径(以 "/images/" 开头的普通前缀匹配):
https://192.168.100.20/images/dogs.jpg ---> 浏览器请求地址
http://192.168.100.35/images/dogs.jpg ---> 实际可能的后端地址
情况 B :
proxy_pass 指令的指令参数带结尾斜杠
若配置文件的内容是类似这样的:
...
events {
...
}
...
http {
...
upstream backend1 {
server 192.168.100.30 max_fails=3 fail_timeout=60s;
server 192.168.100.35 max_fails=3 fail_timeout=60s;
server 192.168.100.40 max_fails=3 fail_timeout=60s;
}
...
server {
listen 192.168.100.20:80;
server_name my-tests.com www.my-tests.com;
return 301 https://www.my-tests.com$request_uri;
}
server {
listen 192.168.100.20:443 ssl http2 backlog=8000 reuseport;
server_name www.my-tests.com;
# SSL/TLS 证书相关的配置
...
# 其他相关的配置
...
# location 上下文的 URL 结尾带了 "/"
location /api/ {
# 指定上游服务器,这里的 URL 在结尾处有带 "/"
proxy_pass http://backend1/;
...
}
}
}
此处,Nginx 代理服务器会将 location 匹配的 URL 路径(以 "/api/" 开头的普通前缀匹配)替换为代理 URL 结尾处的 "/":
https://192.168.100.20/api/index.html ---> 浏览器请求地址
http://192.168.100.35/index.html ---> 实际可能的后端地址
情况 C :踩坑配置与修改
...
http {
...
server {
...
location /api/ {
proxy_pass http://backend1/media;
}
}
}
此处,Nginx 代理服务器会将 location 匹配的 URL 路径(以 "/api/" 开头的普通前缀匹配)替换为代理 URL 结尾处的 "/media":
https://192.168.100.20/api/index.html ---> 浏览器请求地址
http://192.168.100.35/mediaindex.html ---> 实际可能的后端地址
若预期的后端地址是:
http://192.168.100.35/media/index.html
则需要修改成 proxy_pass http://backend1/media/;
* 大多数情况下 location 上下文中的路径需要带末尾斜杠
* 对于代理的 URL 而言,大多数情况下不带末尾斜杠
* 若是子路径替换(上面情况 C 的修改),则
proxy_pass 指令的指令参数的结尾 "/" 与 location 上下文中的路径结尾 "/" 必须成对出现










