[文章作者:张宴 本文版本:v1.0 最后修改:2008.11.28 转载请注明原文链接:http://blog.zyan.cc/post/382/]

  今天在配置Nginx + PHP + MediaWiki中,发现一个问题:MediaWiki所在的Nginx虚拟主机绑定了多个域名,但是不管通过什么域名访问MediaWiki首页,都会被跳转到其中的一个域名上。Nginx配置文件中没有相关的rewrite跳转规则,那么就应该是MediaWiki的PHP程序做的跳转,但是,遍历了MediaWiki目录下的所有文件以及查询了MySQL数据库中的每个表,都没有发现记录有这个域名。后来,通过查看源代码发现MediaWiki是根据$_SERVER['SERVER_NAME']做的跳转,顺藤摸瓜,发现了下列问题:

  在一个Nginx虚拟主机中,可以绑定多个server_name,例如:
  点击在新窗口中浏览此图片

  而server_name的先后顺序的不同,对PHP程序中使用$_SERVER["SERVER_NAME"]或getenv('SERVER_NAME')获取服务器域名是有影响的:
  点击在新窗口中浏览此图片

  点击在新窗口中浏览此图片

  $_SERVER["SERVER_NAME"]或getenv('SERVER_NAME')获取的始终将是Nginx server_name配置中的第一个域名,这一点在程序开发中需要注意。这第一个域名就相当于Apache虚拟主机配置中的ServerName,后面的域名就相当于Apache的ServerAlias。

  PS:以下是网友Daze的留言,希望对本文读者有所帮助。
引用
在某些情况下(具体可参考 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 ,慢慢研究了。 :-)

P.S. nginx 0.7.x 之前的版本还有一个指令 optimize_server_names 会影响内部重定向规则。


Tags: ,



技术大类 » Web服务器 | 评论(60) | 引用(3) | 阅读(125136)
lihaixin Homepage
2008-11-28 22:35
关注nginx,关注张宴!
jack Homepage
2008-11-30 01:57
关注张宴的博客,关注张宴的技术文章
envy
yak
2008-12-1 14:05
nginx 如何自定义日志 比如图请求,js,css请示不记录
CELL
2008-12-13 13:56
用 $_SERVER["HTTP_HOST"] 就可以了
sheaven Email Homepage
2009-1-16 13:04
这个问题或许可以在server{}里面添加 server_name_in_redirect  off; 来解决
sim
2009-3-26 15:33
张兄 关于nginx想请教下 我在装了nginx后编译安装php 大多参数能编译上 但是有几条参数怎么也编译不上

Notice: Following unknown configure options were used:
--with-zip
--enable-url-inclubes
--enable-versioning
--enable-trace-vars

是不是nginx不支持这4条php编译参数? 还是需要用别的方法? 请指教啊
VPS主机 Homepage
2009-4-16 16:46
关注张宴的博客··
crystal Homepage
2009-4-16 16:47
张宴只写技术性的文章吗?
Daze
2009-9-5 19:04
这都是什么跟什么啊?说那么多都没说到点子上!
“$_SERVER["SERVER_NAME"]或getenv('SERVER_NAME')获取的始终将是Nginx server_name配置中的第一个域名”,那是因为 Nginx 把别的都重定向到这第一个域名,想要 Nginx 提供 requested Host header,用 server_name_in_redirect off 啊!
奔跑的企鹅
2009-9-9 12:04
server_name_in_redirect off;
我把它加到server里面了
可是还是不能用啊
各位啊有没有更好的方法呢?
我的 QQ 366204135
用http_host很不爽啊!
Daze
2009-9-23 20:52
对不起,我错了,我上面说的也并不完整。
在某些情况下(具体可参考 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 ,慢慢研究了。 :-)

P.S. nginx 0.7.x 之前的版本还有一个指令 optimize_server_names 会影响内部重定向规则。
ffff
2010-6-1 12:58
这个blog是用wiki作的吗?
吕滔 Email Homepage
2010-7-24 13:35
张老师,我为什么总是配置出错了。。

尤其是 mysql
a12333a
2011-3-27 13:54
谢谢张老师,学习了
dresses Email Homepage
2011-7-26 10:14
Here are a variety of the empire <a href="http://www.romancearound.com/">dresses</a>, I want to introduce yourself. The first shoulder chiffon <a href="http://www.romancearound.com/bridesmaid-dresses-c-197.html">bridesmaid dresses</a> empire style wedding will <a href="http://www.romancearound.com/wedding-dresses-trumpet-wedding-dresses-c-180_253.html">trumpet wedding dresses</a>.This Tia cowries, dressed in her wedding day.Chiffon of the empire the best clothes, because they are the size of the drum as complete motion from the wind the site makes it easy to create a plan impression.One romantic flowers floating above shoulder function and help catch the eyes of the cut of the chest and neck problems, so that more comprehensive coverage of physical illusion bust.Clothing do not like big long torso, short legs, or pear-shaped<a href="http://www.romancearound.com/bridesmaid-dresses-ankle-length-bridesmaid-dresses-c-197_198.html">ankle length bridesmaid dresses</a> figure.special is also suitable for pregnant brides since the mobility as a dress can accommodate more Many of the abdomen.
louis vuitton uk Email Homepage
2011-11-23 09:06
This louis vuitton uk for sale belongs to the sounding just what are termed as Louis Vuitton vintage best sellers, many other products and services for the reason that range appearing companies.You will easily notice the unfold zippers of this coach outlet store online. That is the decoration. There are some inside pockets for you as well. They are easy to match your clothes and to carry.Let us inspire your inner beauty with fine christian louboutin sale. Purse the elegance in bridal wedding. Enjoy the fashion.
Louis Vuitton Neverfull Email Homepage
2012-4-21 17:33
www.lvbagsclassic.com are authorized authentic Louis Vuitton handbags outlet store. All the items at our site are 100% authentic. All our Louis Vuitton handbags will come with the authenticity card, serial Number, dust bag and care booklet. We promise you will be 100% satisfied when you get such cheap authentic Louis Vuitton handbags from us!
Louis Vuitton Neverfull
Hogan
2012-5-10 18:10
Ci sono diversi motivi principali per cui si può sicuramente trovare sul proprio volere le soluzioni contabili che coinvolgono tutta Stansted, anche se alcune persone potrebbero uomini e donne, probabilmente si dovrà disporre di soluzioni contabili rispetto con la gente. Stai con me per scoprire di più su molti dei motivi per prendere in considerazione l'impiego contabili in tutta Hogan Stansted. Costruire un businessIf vi capita di essere in funzione, è abbastanza possibile che si può fare uso di soluzioni contabili. Non date per scontato tutte le società hanno abbastanza soldi per utilizzare a tempo pieno il personale fiscali, così utilizzando una conditi insieme con l'agenzia affidabile che coinvolge tutta commercialisti Stansted potrebbe rendere meno difficili problemi.
分页: 1/4 第一页 1 2 3 4 下页 最后页
发表评论
表情
emotemotemotemotemot
emotemotemotemotemot
emotemotemotemotemot
emotemotemotemotemot
emotemotemotemotemot
打开HTML
打开UBB
打开表情
隐藏
记住我
昵称   密码   游客无需密码
网址   电邮   [注册]