Nginx 301跳转踩坑

Updated on with 1,010 views

问题

Nginx作为反向代理服务器的时候,如果端口设置的特殊,在重定向的时候可能遇到问题。

例如Nginx使用alias命令进行静态页面转发的时候,如果是 .../xxxx1/xxxx2末尾部分是一个文件目录且不以斜杠结尾就回被重定向到 ../xxxx1/xxxx2/

这时候如果Nginx运行在8080,防火墙出口是80,重定向就会出现问题,会重定向到了Nginx的8080端口。

浏览器表现的就是 www.xxxxx.com:8080/dir/被防火墙拦截导致访问失败

原因分析

为啥服务端会返回301自动重定向呢?首先需要弄清楚状态码的含义。HTTP协议中3xx开头的状态响应码都是表示重定向的响应。根据RFC的定义:

301 Moved Permanently
302 Found
303 See Other
307 Temporary Redirect

301是永久重定向。如果使用Nginx作为HTTP服务器,那么当用户输入一个不存在的地址之后,基本上会有两种情况:

404 Not Found 页面未找到
301 Moved Permanently 码和重定向地址

然而要不要进行页面重定向,和怎么重定向,按道理说完全是用户配置的结果
但是有一种情况下Nginx会主动设置301 Moved Permanently,当用户在浏览器输入了一个url地址,末尾部分是一个文件目录且不以斜杠 /结尾,比如 www.xxxx.com/index

Nginx没有找到index这个文件,但发现了index是个目录。于是本次访问的返回状态码就会被设置成301 Moved Permanently。

解决方案

一般情况下,我们会在nginx.conf中配置absolute_redirect,server_name_in_redirect和port_in_redirect,以便到达个性化的重定向功能。其中absolute_redirect控制Location url的生成方式。

  • absolute_redirect设置成on,则生成绝对路径作为Location url
  • absolute_redirect设置成off,则生成相对路径作为Location url。

只有absolute_redirect设置为on时,另外两个配置才会生效。

  • server_name_in_redirect为on时,使用Nginx配置文件中的server_name作为Location url中的host,否则使用用户请求url中的主机名作为host;
  • port_in_redirect设置为on时,使用nginx监听的端口来构造Location url,否则不设置port。

最简便的解决方法便是,设置absolute_redirect为off,构造相对路径作为Location的url

server {
listen 8080;
# 设置相对url重定向
absolute_redirect off;
……
}

Responses
取消