nginx在重定向时端口出错的问题

  1. 当访问的uri最后不带斜杠时,例如 http://localhost/product ,会先查找 product 文件,存在就返回;若存在 product 文件夹,会在末尾加上一个斜杠并产生 301 跳转。

  2. 当访问的uri最后带斜杠时,例如 http://localhost/product/,查找 product 下的 index 页面,存在就返回;不存在且未开启自动索引目录选项(autoindex on)则报 403 错误。

在第一种情况,访问带目录的url时,如果末尾不加斜杠(“/“),nginx默认会加上斜杠,发生一次301跳转,但这个默认行为在nginx前端有LB负载均衡器、且LB监听的端口与nginx server监听的端口不同时会导致访问出错。

但这个默认行为在nginx前端有LB负载均衡器、且LB监听的端口与nginx server监听的端口不同时会导致访问出错。

可以使用docker模拟错误

1
2
3
4
5
6
7
8
9
10
11
12
# nginx配置文件 /tmp/nginx.conf
server {
listen 81;
location /test/ {
proxy_pass http://127.0.0.1:82;
}
}
server {
listen 82;
add_header Content-Type text/plain;
return 200 $uri;
}
1
2
# 启动docker,将容器81端口映射到本地8181端口
docker run --name my-custom-nginx-container -p 8181:81 -v /tmp/nginx.conf:/etc/nginx/conf.d/default.conf -d nginx

浏览器访问http://127.0.0.1:8181/test 后发现,nginx在末尾添加斜杠重定向时,端口会被重定向到81端口,会访问到 http://127.0.0.1:81/test/ ,由于本地宿主机只监听了8181端口所以会无法访问。

使用curl 看一下过程

1
2
3
4
5
6
7
8
9
curl -v http://127.0.0.1:8181/test

< HTTP/1.1 301 Moved Permanently
< Server: nginx/1.17.7
< Date: Fri, 17 Jan 2020 08:15:40 GMT
< Content-Type: text/html
< Content-Length: 169
< Location: http://127.0.0.1:81/test/
< Connection: keep-alive

解决方案

  1. 对外对内使用相同的端口号,如都修改成8181或者81,但治标不治本。

  2. nginx配置添加absolute_redirect off; ,可以取消绝对路径的重定向。

1
2
3
4
5
6
7
8
9
10
11
12
13
# 修改nginx配置文件 /tmp/nginx.conf
server {
listen 81;
absolute_redirect off; #取消绝对路径的重定向
location /test/ {
proxy_pass http://127.0.0.1:82;
}
}
server {
listen 82;
add_header Content-Type text/plain;
return 200 $uri;
}

删除容器重新启动再次测试,可以发现Location已经变成相对路径了

1
2
3
4
5
6
7
8
9
curl -v http://127.0.0.1:8181/test

< HTTP/1.1 301 Moved Permanently
< Server: nginx/1.17.7
< Date: Fri, 17 Jan 2020 08:29:45 GMT
< Content-Type: text/html
< Content-Length: 169
< Connection: keep-alive
< Location: /test/

如果没有生效,请检查nginx是否版本过低