浅析nginx配置server_name为多个时的坑
一、问题背景
我们一个服务器设置了2个域名,分别对应2个项目。监听 80 端口写了2个 server_name。比如这样server_name配置改为:
# 只列出了我们关心的配置,省略了其他无关部分
server {
server_name www.abc.com test.dce.com;
}
见这篇文章有类似问题:https://blog.csdn.net/u011296355/article/details/106740860
二、问题定位
根据业务上报错时打的日志,定位到请求公共处理的部分里有这么一个判断:
if ($_SERVER['SERVER_NAME'] != parse_url($_SERVER['HTTP_REFERER'], PHP_URL_HOST)) {
$this->redirectError();
}
判断请求referer里解析出的域名如果和nginx里的$server_name变量里的域名如果不一样,就跳到错误页面,也是前面说的问题。
那么问题来了,看referer中的域名为什么和 $_SERVER['SERVER_NAME'] 不一致呢?我请求用的链接形式如 http://test.daemoncoder.com/xxx 这种形式,但是最终在PHP这一层取到 $_SERVER['SERVER_NAME'] 的值为 www.daemoncoder.com,而 HTTP_REFERER 里的域名为:test.daemoncoder.com。
可以看到 SERVER_NAME 的取值和我们的预期不一致,nginx是怎么把这个变量传过来的,需要从 nginx 的 fastcgi_params 配置文件中找一下 SERVER_NAME 的定义:
fastcgi_param SERVER_NAME $server_name;
可以看到 nginx 里的 $server_name 变量就是我们PHP里取的$_SERVER['SERVER_NAME'] 的来源。
三、问题的原因
通过上面的定位,我们基本可以看到问题的根本原因了:
当nginx配置里一个server节点下,server_name配置多个域名时,$server_name变量的值都是配置的第一个。
再回顾下我的 nginx 配置,所以就知道 $server_name 始终是 www.abc.com 的原因了。
四、解决方式
1、第一种方式就是把配置文件按域名拆分到各自单独的server节点下,也就是
# 省略其他无关部分
server {
server_name www.abc.com;
}
server {
server_name test.dce.com;
}
这样用不同的域名访问会落到各自对应的配置中,解析到的 $server_name 也都是各自的值。
2、第二种方式是修改 nginx SERVER_NAME 使用 $host 变量, 也就是把
fastcgi_param SERVER_NAME $server_name;
// 修改为:
fastcgi_param SERVER_NAME $host;
3、$host 变量的解析都是当前请求的host,不会受 server_name 是否配置多个域名的影响。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律