首页 » web服务, 操作系统 » nginx proxy pass 反向代理中的URL目录没有斜杠结尾的问题

nginx proxy pass 反向代理中的URL目录没有斜杠结尾的问题

时间:2014-01-15作者:felix.chan分类:web服务, 操作系统评论:0

最近用nginx proxy pass +proxy_cache来做前端反向代理兼cdn缓存服务器。发现一个很奇怪的问题:有部分人反馈用ie浏览器访问http://www.rednat.com/mydir 时无法正常显示,我用chrome测试也会偶尔出现类似问题,IE测试每次都会出现,查看nginx日志发现记录的是http 301 永久重定向。最后终于定位到原来nginx 在反向代理时是无法区分mydir到底是目录还是文件名,如果用http://www.rednat.com/mydir/ 后面加个斜杠的方式访问则全部正常。

解决方案有两种:
方案1:使用rewrite对目录结尾的但是后面又没斜杠的,重新加个斜杠
rewrite /mydir$ $scheme://$host$uri/ permanent;

但是这样rewirte只能解决某个特定的目录的问题,如果存在很多的目录,那就比较麻烦了。

方案2:server_name_in_redirect off 解决

看了下面的描述之后,终于发现,可能是由于没有配置 server_name_in_redirect off 这个参数,导致访问的地址被重定向到第一个vhost的域名上了。

在某些情况下(具体可参考 wiki.nginx.org),Nginx 内部重定向规则会被启动,例如,当 URL 指向一个目录并且在最后没有包含“/”时,Nginx 内部会自动的做一个 301 重定向,这时会有两种情况:
1、server_name_in_redirect on(默认),URL 重定向为: server_name 中的第一个域名 + 目录名 + /;
2、server_name_in_redirect off,URL 重定向为: 原 URL 中的域名 + 目录名 + /。

当你有多个域名要指向同一个虚拟主机,并且你自己写 301 重定向规则把它们合并到某一个域名时,情况就更复杂了:
首先,nginx 检查 URL,如果符合条件,就用该规则(你写的)做第一遍重定向,接着,检查新生成的 URL,如果符合内部自动重定向之条件,就用前面提到的规则再做一次重定向。

至于 PHP 的 $_SERVER["SERVER_NAME"],在 nginx 中默认是由 nginx 的变量 $server_name 提供,这时它和重定向没有关系,始终是 server_name 设置中的第一个域名,但这是可以被改变的,在你的 nginx 配置中找到 fastcgi_param 部分,修改
fastcgi_param SERVER_NAME $server_name;

fastcgi_param SERVER_NAME $host;
但现在就要注意了,此时的 $_SERVER["SERVER_NAME"] 会受你写的和 nginx 自己的重定向规则所影响而变化。

现在就清楚了,如果 MediaWiki 是通过 $_SERVER["SERVER_NAME"] 来自己处理 URL 的话,那么在 nginx + php 的默认环境下,它获得的将始终是 server_name 设置中的第一个域名,所以造成了“不管通过什么域名访问 MediaWiki 首页,都会被跳转到其中的一个域名上。”,这不是 nginx 的重定向造成的,虽然默认 server_name_in_redirect 是 on,但这个指令的影响范围仅仅只是 nginx 自己内部的重定向规则,所以,当你在 nginx + php 的环境中使用多域名虚拟主机,并且你的 php 库、框架、代码大量使用 $_SERVER["SERVER_NAME"] 时,你也许应该:
1、设置 fastcgi_param SERVER_NAME $host;
2、设置 server_name_in_redirect off; 让 nginx 在处理自己内部重定向时不默认使用 server_name 设置中的第一个域名;
3、不要使用 nginx 的 rewrite 规则来重定向、合并多个域名。
当然,后俩条是完全可选的,前提是你清楚你在做什么并且小心处理这时的 $_SERVER["SERVER_NAME"],也许更好的做法是保持 fastcgi_param SERVER_NAME $server_name; ,然后合理使用 $_SERVER["SERVER_NAME"] 和 $_SERVER["HTTP_HOST"]。

这个问题确实很微妙,也许我的理解还是不完全,好在还有 curl ,慢慢研究了。 :-)

原创文章,转载请注明: 转载自红防联盟www.rednat.com

本文链接地址: nginx proxy pass 反向代理中的URL目录没有斜杠结尾的问题

|2|right
0 条评论

暂时没有评论!

发表评论

电子邮件地址不会被公开。 必填项已用 * 标注

您可以使用这些 HTML 标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>