Nginx虚拟主机多server_name的顺序问题
今天在配置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的留言,希望对本文读者有所帮助。
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 会影响内部重定向规则。
Nginx虚拟主机多server_name的顺序问题的更多相关文章
- Nginx高性能服务器安装、配置、运维 (5) —— Nginx虚拟主机配置
六.Nginx虚拟主机配置 建立基于域名的虚拟主机: (1)建立基于域名的虚拟主机配置文件(以abc.com为例): (2)更改虚拟主机配置文件: 更改配置如下(更改部分即可): server { l ...
- Linux(7)- Nginx.conf主配置文件、Nginx虚拟主机/访问日志/限制访问IP/错误页面优化、Nginx反向代理、Nginx负载均衡
一.Nginx.conf主配置文件 Nginx主配置文件conf/nginx.conf是一个纯文本类型的文件,整个配置文件是以区块的形式组织的.一般,每个区块以一对大括号{}来表示开始与结束. 核心模 ...
- nginx虚拟主机配置
nginx虚拟主机配置 虚拟主机的概念虚拟主机,就是把一台物理服务器划分成多个"虚拟"的服务器,每一个虚拟主机都可以有独立的域名和独立的目录nginx虚拟主机的配置nginx的 ...
- Apache与Nginx虚拟主机设置(多域名和多端口的区别)
为了方便管理虚拟主机,应该尽量少修改主配置文件http.conf或者nginx.conf,大部分修改变更都在虚拟主机片配置文件httpd- vhost.conf或者vhost.conf中完成,这样有利 ...
- Nginx教程(二) Nginx虚拟主机配置
Nginx教程(二) Nginx虚拟主机配置 1 虚拟主机管理 1.1 Nginx管理虚拟主机 虚拟主机使用的是特殊的软硬件技术,它把一台运行在因特网上的服务器主机分成一台台“虚拟”的主机,每台虚拟主 ...
- 配置Nginx虚拟主机
实验环境 一台最小化安装的CentOS 7.3虚拟机 配置基本环境 1. 安装nginx yum install -y epel-* yum isntall -y nginx vim 2. 建立虚机主 ...
- Nginx教程--02.Nginx虚拟主机的配置
1.Nginx虚拟主机的配置 1.1 在conf目录下,使用命令 : vim nginx.conf 对上图解释: //全局区 worker _processes 1; //表示当前有1个工作的子进程, ...
- php管理nginx虚拟主机shell脚本
使用php作为shell脚本是一件很方便的事情.理所当然,我们可以使用php脚本来管理 nginx虚拟主机,下面是笔者的 脚本 文件供各位参考 代码如下 复制代码 #!/usr/bin/php -q& ...
- Nginx 虚拟主机 VirtualHost 配置
Nginx 是一个轻量级高性能的 Web 服务器, 并发处理能力强, 对资源消耗小, 无论是静态服务器还是小网站, Nginx 表现更加出色, 作为 Apache 的补充和替代使用率越来越高. 我在& ...
随机推荐
- SSM到Spring Boot入门与综合实战
一:Spring从入门到进阶 1 Spring入门 1.1 Spring IOC的底层实现原理:工厂 + 反射 + 配置文件 <bean id="us" class=&quo ...
- [转贴]Linux内核LTS长期支持版生命周期
Linux内核LTS长期支持版生命周期 https://blog.51cto.com/dangzhiqiang/1894026 搞不懂长期支持版本的特点和区别. 党志强关注0人评论4371人阅读201 ...
- js数据结构-链表
链表和数组 大家都用过js中的数组,数组其实是一种线性表的顺序存储结构,它的特点是用一组地址连续的存储单元依次存储数据元素.而它的缺点也正是其特点而造成,比如对数组做删除或者插入的时候,可能需要移动大 ...
- hashmap存储数据
在HashMap中,为什么不能使用基本数据类型作为key? 其实和HashMap底层的存储原理有关,HashMap存储数据的特点是:无序.无索引.不能存储重复元素. 存储元素采用的是hash表存储数据 ...
- python cx_oracle 环境搭建
背景说明: 之前的环境本来是可以用的,是另外一个项目(python27)需要的时候搭建的.新项目采用的是python36,安装的cx_oracle的版本是7,而环境中的Oracle客户端是11,导致p ...
- js实现复制内容到剪贴板
一. 原生js实现,电脑可以用,手机不可以用 1. 必须是 input元素 才可以使用 <input id="code" type="text" valu ...
- powerDisgner 数据类型对比
powerDisgner 16.5版本支持一下类型数据模型格式 以下数字数据类型可用: Standard data type DBMS-specific physical data type Cont ...
- HTML和CSS学习
HTML和CSS HTML 基础讲解 要点: 标记语言不是编程语言 .html和.htm都是html文档的后缀 标签有围堵和自闭两类 开始标签中可以定义属性,属性的值要用引号引起来 H5一般用于移动端 ...
- Scala新版本学习(1):
1.进官网:https://www.scala-lang.org/ 上面就是进入Scala社区后的一个画面,官方对Scala的简单介绍是:Scala将面向对象和函数式编程集合在一个简洁的高级语言中,S ...
- 富文本编辑器--引入demo和简单使用
wangEditor —— 轻量级 web 富文本编辑器,配置方便,使用简单.支持 IE10+ 浏览器. 官网:www.wangEditor.com 文档:www.kancloud.cn/wangfu ...

2008-11-28 11:27 | by