nginx 访问目录是没加/的重定向控制 引发的血案

缘由

在前段时间我们进行服务器迁移的过程中 由于使用了多服务器 增加了反向代理,导致页面在另一台机器打不开。原因是因为我们触发了一个nginx默认规则,这里记录一下仅供大家参考。

演示环境

基础信息

域名:www.testnginx.com  

目录结构:

.
├── a
│   └── index.html
└── a.html

注解:在根目录,我们有一个 a.html 和 a的文件夹

nginx配置

server {
    charset utf-8;
    client_max_body_size 128M;
    listen 80;
    server_name www.testnginx.com;
    root /data/www/php_waibao/testnginx;
    index index.html;
}

演示案例

案例一:访问 http://www.testnginx.com/a   会发生什么?

结论:当访问的路径是一个目录的时候,nginx 会进行 301 永久调整 增加一个 / 。也就是上面的问题会看到浏览器地址栏的网址从 http://www.testnginx.com/a 变成 http://www.testnginx.com/a/ 

如下图 浏览器的网络请求:验证了结论

600


600


案例二:访问 http://www.testnginx.com/c   会发生什么?

结论:由于目录下既没有c的文件,也没有c的目录 所以会报错404

600

总结

当 我们在 访问 一个目录的时候,如果网址后面没有 /,nginx会自动进行 301 跳转到 加了 /的网址(前提是目录存在) 。这是一个非常简单并且容易被忽视的一个规则

缘由到底发生了什么事情

既然称之为 “血案”,肯定是有复杂的地方。我用一个架构图给大家说明下。

600


600


从上图我们可以看到,服务器A的业务处理在 81,服务器B的业务处理在 80。基于前面演示问题一,我们再来看看会出现什么问题

请求落到服务器B

没任何问题,http://www.testnginx.com/a 变成 http://www.testnginx.com/a/  ,访问正常

请求落到服务器A

悲剧就这样发送了,http://www.testnginx.com/a 变成 http://www.testnginx.com:81/a/  ,访问不正常(因为高防服务器开特殊端口需要申请的)


从上面我们就可以看出就是一个很简单的问题导致的,由于我们常用80端口 这个问题会被隐藏起来,当使用其他端口就会立即暴露出来


解决方案

方案一

写代码链接的时候规范化,保证链接网址

方案二

在nginx中增加一个配置就可以解决

##如果有这个目录那就帮忙重定向到目录
if (-d $request_filename){
   rewrite ^/(.*)([^/])$ http://$host/$1$2/ permanent;
}

注解:nginx强制判断如果是目录的话,直接修改了重定向网址就行了