最近开发环境部署网站时发现 nginx 会自动做一个 301 跳转,原因是探测访问路径目录是否存在,比如 /login 如果检测到有 login 目录,就会自动 301 到 /login/ 路径,但是重定向过程中发现了一点问题。
单机部署的情况下是没有问题的,但是当使用 docker 做了端口映射时就出现了问题。
如图中,docker 暴露的是 30080 端口,但是部署的 nginx 配置的是 80 端口,就导致了看上去是端口丢失的问题(其实端口并没有消失,只是 80 默认不显示)。
本地搭建了一个环境测试,使用 Docker 启动
server {
listen 8000;
listen [::]:8000;
server_name localhost;
}
docker run -p 9000:8000
访问 9000 端口时被 301 重定向到了 8000 端口,因为 Nginx 内部使用的是 8000。
找到问题就好说,想到两种解决方案,一是 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;
测试成功通过,浏览器访问后自动重定向到 http://localhost:9000/login/
。
跟这个指令有关联的还有 server_name_in_redirect
和 port_in_redirect
指令, absolute_redirect
关掉后,这两个会自动关闭,按需使用即可。
比如上图中,关掉了 server 和 port 的指令,因为 server name 没有 80 那种默认的端口,所以 server name 自动从 host 字段中获取域名。