Published on
656

nginx目录跳转斜杠问题以及对应解决方案

Authors
  • avatar
    Name
    小辉辉
    Twitter

事情的来源:

静态资源部署到nginx上面,如果访问的地址不是一个实际资源,会当作是一个目录来寻找,这时会触发301跳转到带/的地址。正常来说这样跳转的话,不会有什么异常问题。

平时在使用dumi编译出来的项目,生成的路由结尾默认是不带/的,会发现它的路由机制又会把结尾的/去掉。就这一个操作,如果用户现在将当前页面加入书签,再次打开的时候,就会触发一次前面所说nginx的跳转操作。

一般情况下这样子也不会有问题,但是当我们的工程是部署在另外一个服务的下游时,进行跳转时,会导致跳转到当前部署的工程端口下面,这样麻烦就来了,具体表现为上游的服务用的是3000端口,前端资源用的是80端口,跳转的时候会跳转到80端口的资源下面去,那这样的话就会和上游服务的端口匹配不上导致页面无法打开。

对于这个问题我个人比较期望的解决方案是能不能不要触发nginx的跳转,直接输出当前文件夹下面对应的index.html文件,一开始不知道怎么描述这个问题,所以找了很久才知道有个rewrite的功能,相关实现如下:

rewrite ^([^.]+)$ $1/index.html last;

这段代码的作用就是提取不包括带.的地址(用于排除静态资源文件),提取后会返回该目录下的index.html文件,最后的last标识表示该rewrite是最后一条指令,但是可以继续后面的其他操作,如果不想执行后面的其他操作可以替换为break

详细的使用文档可以参考这里: https://nginx.org/en/docs/http/ngx_http_rewrite_module.html

除了这个解决方案外,我们还可以通过另外一种方法解决,那就是让nginx跳转到正确的端口,通过查找资料可以知道,这里nginx本身就提供了一个指令叫做absolute_redirect,这个功能就是绝对路径跳转,默认是开启的,我们只需要设置off即可,最后我们看到的效果是location: /xxxx,会发现主机和端口地址都会去除,这样一来就可以正常重定向。

absolute_redirect off;

详细的使用文档可以参考这里:https://nginx.org/en/docs/http/ngx_http_core_module.html#absolute_redirect

总结:两种方案都能解决问题,个人倾向于第一种。