nginx中tryfiles引起301重定向

背景

公司官网项目,通过两层 nginx 请求数据,发现重定向后地址带上了端口,如:
https://wwww.kch8.top:18000/test?name=huang

项目架构

第一层 nginx

第一层通过代理转发到第二层

1
2
3
4
5
6
7
8
9
10
11
server
{
listen 80;
listen 443 ssl http2;
server_name www.kch8.top kch8.top;

location /
{
proxy_pass http://www.kch8.top:8081
}
}

第二层 nginx

第二层是 vue 项目,采用 history 模式,故用 try_files 解决浏览器刷新 404 问题

1
2
3
4
5
6
7
8
9
10
11
12
server
{
listen 8081;
server_name www.kch8.top kch8.top;
index index.php index.html index.htm default.php default.htm default.html;
root /data/web/www.kch8.top/dist;

location /
{
try_files $uri $uri/ /index.html;
}
}

问题分析

301 问题

第一层只做转发,一般没有问题;往下排查,第二层可能性最大;try_files 引起的一次重定向

try_files 说明

try_files 指令后面可带多个 uri,进行多次匹配,直到找到相关资源为止。
针对上面try_files $uri $uri/ /index.html
请求的 url 为:https://www.kch8.top/product/detail?productId=100000
站点部署结构为:

1
2
3
4
5
.
├── index.html
└── product
└── detail
└── index.html

上述请求 uri 为/product/detail,根据 try_files 配置,匹配如下:
a. $uri进行匹配,资源文件不存在;
b. 向下$uri/匹配,发现 detail 文件夹存在,则返回 301 地址https://www.kch8.top/product/detail/?productId=100000(detail 文件下存在默认 index.html 文件,并没有匹配 index.html 内容,这和 location 下 uri 匹配有区别)
c. b 步骤不匹配,则找根目录下 index.html,最后这个 uri 一定要存在,否则会报 404 错误;(最后这个匹配是内部重定向,而不是下发 301 或 302 这种)

重定向带端口问题

这个问题是由 try_files 产生了一次重定向,生成的 url 为https://www.kch8.top:8081/product/detail/?productId=100000
url 中域名是通过 server_name 获取;
url 中端口是通过 listen 获取;

解决方案

301 问题

根据站点,根目录文件层级,try_files 做出如下修改:

1
try_files $uri $uri/index.html /index.html

对第二个 uri,直接找目录下的 index.html 文件

重定向带端口问题

重定向 url 中的域名,可以通过server_name_in_redirect控制,默认开启,官方解释:

1
Enables or disables the use of the primary server name, specified by the server_name directive, in absolute redirects issued by nginx. When the use of the primary server name is disabled, the name from the “Host” request header field is used. If this field is not present, the IP address of the server is used.

重定向 url 中的端口,可以通过port_in_redirect控制,默认开启,官方解释:

1
Enables or disables specifying the port in absolute redirects issued by nginx.

关闭绝对重定向,可以通过absolute_redirect控制,默认开启,官方解释:

1
If disabled, redirects issued by nginx will be relative.

故将absolute_redirect设置为off,改为相对重定向,避免出现端口问题

参考资料

  1. https://blog.csdn.net/weixin_44457062/article/details/125890694
  2. http://nginx.org/en/docs/http/ngx_http_core_module.html#port_in_redirect

nginx中tryfiles引起301重定向

http://www.kch8.top/2024/01/25/nginx-tryfiles-301/

发布于

2024-01-25

更新于

2024-06-24

许可协议

评论