随笔

Nginx 301 丢失端口问题

最近开发环境部署网站时发现 nginx 会自动做一个 301 跳转,原因是探测访问路径目录是否存在,比如 /login 如果检测到有 login 目录,就会自动 301 到 /login/ 路径,但是重定向过程中发现了一点问题。

单机部署的情况下是没有问题的,但是当使用 docker 做了端口映射时就出现了问题。

如图中,docker 暴露的是 30080 端口,但是部署的 nginx 配置的是 80 端口,就导致了看上去是端口丢失的问题(其实端口并没有消失,只是 80 默认不显示)。

1

本地搭建了一个环境测试,使用 Docker 启动

server {
    listen       8000;
    listen  [::]:8000;
    server_name  localhost;
}
docker run -p 9000:8000

访问 9000 端口时被 301 重定向到了 8000 端口,因为 Nginx 内部使用的是 8000。

2

找到问题就好说,想到两种解决方案,一是 docker 把映射的端口和内部 nginx 的端口保持一致,比如

docker run -p 9000:8000 -> docker run -p 8000:8000

这样就不会因为 nginx 获取不到 docker 的端口而出现问题,但是限制了场景,内外必须保持一致。

第二种肯定是去翻 nginx 配置了,先去问了 GPT 回答的驴头不对马嘴,可能因为是 GPT 3.5 的原因,都是让我手动指定域名和端口,但是 nginx 那里肯定不能固定端口和域名。

后来从文档中找到 absolute_redirect 指令,直译过来就是绝对路径重定向,回到刚才截图中,Location 给出的地址是绝对地址,如果改成相对地址是不是就可以了呢?

absolute_redirect off;

3

测试成功通过,浏览器访问后自动重定向到 http://localhost:9000/login/

跟这个指令有关联的还有 server_name_in_redirectport_in_redirect 指令, absolute_redirect 关掉后,这两个会自动关闭,按需使用即可。

4

比如上图中,关掉了 server 和 port 的指令,因为 server name 没有 80 那种默认的端口,所以 server name 自动从 host 字段中获取域名。

本文链接:https://note.lilonghe.net/post/nginx-301-diu-shi-duan-kou-wen-ti.html

-- EOF --