记一个nginx server_name配置多个域名时的坑

server_name 指令详解

        server_name 指令设置基于域名的虚拟主机,⼀个ip的服务器可以配置多个域名。下⾯这些server_name是有效的:

  • server_name domain.com;
  • server_name domain.com www.domain.com;
  • server_name *.domain.com;
  • server_name .domain.com;
  • server_name domain.*;
  • server_name "";

        多个域名之间以空格分隔。nginx允许⼀个虚拟主机有⼀个或多个名字,也可以使⽤通配符"*"来设置虚拟主机的名字。

server_name指令在接到请求后的匹配顺序分别为:

  • 1、准确的server_name匹配,例如:domain.com www.domain.com
  • 2、以通配符开始的字符串: .domain.com  .domain.com
  • 3、以通配符结束的字符串:www.
  • 4、匹配正则表达式:~^(?.+).domain.com$

        nginx将按照1,2,3,4的顺序对server name进⾏匹配,有⼀项匹配以后就会停⽌搜索,类似于location指令。

背景

        为了区分线上环境和测试环境,我弄了个自己测试专用的域名test.daemoncoder.com,线上环境的正式域名是www.daemoncoder.com。nginx里的server_name配置改为:

# 只列出了我们关心的配置,省略了其他无关部分
server {server_name www.daemoncoder.com test.daemoncoder.com;...
}

        但是使用时发现请求一直报错,重定向到错误页面,于是开始了问题的定位。

问题的定位

        根据业务上报错时打的日志,定位到请求公共处理的部分里有这么一个判断:

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 {server_name www.daemoncoder.com test.daemoncoder.com;...
}

        server_name 结点有两个:www.daemoncoder.com 和 test.daemoncoder.com,当我用测试域名去访问页面的时候,可以匹配到 test.daemoncoder.com 这个域名,所以会根据当前这个server节点的配置来处理这个请求,但是 nginx 会把 $server_name 的值设置为当前 server 节点的配置的第一个 server_name,也就是 www.daemoncoder.com。如果配置改为:

server_name test.daemoncoder.com www.daemoncoder.com;

        那么用测试域名请求就可以得到期望的值了(但是正式域名就出问题了)。

解决方式

第一种方式就是把配置文件按域名拆分到各自单独的server节点下,也就是:

# 省略其他无关部分
server {server_name www.daemoncoder.com;...
}
server {server_name test.daemoncoder.com;...
}

这样用不同的域名访问会落到各自对应的配置中,解析到的 $server_name 也都是各自的值。

第二种方式是修改 nginx SERVER_NAME 使用 $host 变量, 也就是把 

fastcgi_param SERVER_NAME $server_name;

修改为:

fastcgi_param SERVER_NAME $host;

        $host变量的解析都是当前请求的host,不会受 server_name 是否配置多个域名的影响,这样我们在PHP里取 $_SERVER['SERVER_NAME'] 取出的值就是实际请求的域名,也可以解决问题(但是代码里的这个判断逻辑在测试环境似乎就没有意义了,问题不大)。

其他

        有多个域名时(server_name other.domain.com www. domain.com;):fastcgi_param SERVER_NAME $server_name ,$server_name 会取值第一个域名(other.domain.com)。

        $host 有可能等于 $server_name ,也可能是IP地址(直接通过访问此优先顺序取值:请求行中的主机名,或“主机”请求标头字段中的主机名,或与请求匹配的服务器名。

  $1|$2|$3 ...是nginx在匹配正则时生成的变量,用于捕获一个正则表达式括号中匹配的字符串(从左到右依次存储在$1|$2|$3 ...中),新值覆盖旧值,可以使用变量保存需要用到的值set $pre $1

参考

https://www.daemoncoder.com/a/%E8%AE%B0%E4%B8%80%E4%B8%AAnginx%20server_name%E9%85%8D%E7%BD%AE%E5%A4%9A%E4%B8%AA%E5%9F%9F%E5%90%8D%E6%97%B6%E7%9A%84%E5%9D%91/4d6a513d

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/11115.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【ESP32】开发笔记

​ 一、搭建开发环境 开发环境基于Windows操作系统,VSCode编译器,Espressif IDF插件。 1.ESP-IDF SDK及环境 下面两种链接任选其一,建议选择【ESP32】ESP-IDF安装 【ESP32】ESP-IDF安装 【ESP32】Espressif-IDE及ESP-IDF安装 2.【VSCode】…

利用sklearn 实现线性回归、非线性回归

代码: import pandas as pd import numpy as np import matplotlib import random from matplotlib import pyplot as plt from sklearn.preprocessing import PolynomialFeatures from sklearn.linear_model import LinearRegression# 创建虚拟数据 x np.array(r…

Python操作Excel文件,修改Excel样式(openpyxl)

秋风阁-北溪入江流 文章目录 安装依赖库openpyxlopenpyxl的操作加载文件,获取sheet加载文件load_workbook获取sheet 遍历单元格迭代遍历索引遍历 单元格行高和列宽的修改Excel列号与字母的转换Excel行高修改Excel列宽修改 Excel表格文字对齐属性设置修改单元格框线保…

浮标水质监测站现场水质自动监测仪

浮标水质监测站是设立在河流、湖泊、水库、近岸海域等流域内进行现场水质自动监测的监测仪器,是以水质监测仪为核心,运用传感器技术,结合浮标体、电源供电系统、数据传输设备组成的放置于水域内的小型水质监测系统。用于连续自动监测被测水体…

Python的用处到底是什么?(一)

1. 网络爬虫:使用Python的库,如BeautifulSoup,可以轻松地从网页中提取数据。 当涉及到从互联网上收集大量数据时,Python是一个非常强大的语言,它提供了许多用于网络爬虫的库和工具。其中最常用的库之一是BeautifulSou…

DAY3,Qt(完成闹钟的实现,定时器事件处理函数的使用)

1.完成闹钟的实现&#xff0c;到点播报文本框的内容&#xff1b; ---alarm.h---头文件 #ifndef ALARM_H #define ALARM_H#include <QWidget> #include <QTimerEvent> //定时器处理函数类 #include <QTime> //时间类 #include <QPushButton> //按钮…

蓝牙技术|智能照明市场蓬勃发展,蓝牙技术助力市场发展

照明控制系统在商业和工业领域的应用广泛。例如&#xff0c;智能办公楼、商场、工厂等场所&#xff0c;可以通过照明控制系统实现节能和舒适性的提升。预计将从2023年的74亿美元增长到2032年的108亿美元&#xff0c;复合年增长率(CAGR)为4.3%。 随着LED照明技术在市场上的逐渐普…

QT DAY3

1.思维导图 2.完成闹钟的实现 头文件 #include <QTextToSpeech> #include <QTextEdit> QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACEclass Widget : public QWidget {Q_OBJECTQLineEdit *edit1new QLineEdit;// QTextEdit *edit2new QTe…

什么是DPA实验,DPA的应用场景行业及可检测的问题要点总结

🏡《电子元器件学习目录》 目录 1,什么是DPA实验2,DPA的起源与应用行业3,DPA的应用场景4,DPA可检测的问题4.1,性能下降4.2,工艺问题4.3,结构问题4.4,可靠性问题4.5,交货检验5,总结1,什么是DPA实验 DPA是Destructive Physical Analysis的缩写,DPA实验又被称为破坏…

java版企业工程项目管理系统 Spring Cloud+Spring Boot+Mybatis+Vue+ElementUI+前后端分离 功能清单

Java版工程项目管理系统 Spring CloudSpring BootMybatisVueElementUI前后端分离 功能清单如下&#xff1a; 首页 工作台&#xff1a;待办工作、消息通知、预警信息&#xff0c;点击可进入相应的列表 项目进度图表&#xff1a;选择&#xff08;总体或单个&#xff09;项目显示…

新手小白学习SWAT模型【建模方法、实例应用、高级进阶】

目录 第一部分&#xff1a;SWAT模型实践部分 第二部分&#xff1a;SWAT模型【进阶部分】 更多推荐 【专家】&#xff1a;刘老师【副教授】&#xff0c;北京重点高校资深专家&#xff0c;和美国SWAT软件开发方长期合作&#xff0c;拥有丰富的科研及工程技术经验&#xff0c;长…

【双指针优化DP】CF985E

Problem - 985E - Codeforces 题意&#xff1a; 思路&#xff1a; 首先肯定需要排个序&#xff0c;然后分段DP 但是平常写的分段DP都是n^2的&#xff0c;这里的可以发现单调性&#xff0c;因此考虑双指针转移 这里两个指针都代表两个段的右端点 Code&#xff1a; #includ…

MySQL-MHA高可用配置及故障切换

MySQL-MHA 一、MHA概述&#xff1a;1.概述&#xff1a;2.MHA的组成&#xff1a;3.MHA的特点&#xff1a;4.MHA的工作原理&#xff1a; 二、搭建MySQL MHA&#xff1a;1.配置主从复制&#xff1a;2.配置MHA&#xff1a;3.manager与node工具使用&#xff1a;4.在 manager 节点上配…

Redis优惠券秒杀超卖问题

Redis秒杀超卖问题 前言一、出现秒杀超卖的原因二、超卖解决方案使用乐观锁解决超卖问题程序中进行解决 前言 这是我认为b站上最好的redis教程&#xff0c;各方面讲解透彻&#xff0c;知识点覆盖比较全。 黑马redis视频链接&#xff1a;B站黑马redis教学视频 本文参考黑马redi…

vue使用qrcodejs2-fix或者qrcodejs2插件生成二维码

1. vue2安装 npm i qrcodejs2 1.1. vue3安装 npm install qrcodejs2-fix 2. 组件中引入并封装成公共组件&#xff0c;vue3版 <template><!-- 二维码生成 --><div class"body-div"><div style"width: 100%;height: 100%;" :id&quo…

入门Linux基本指令(2)

这篇文章主要提供一些对文件操作的Linux基本指令&#xff0c;希望对大家有所帮助&#xff0c;三连支持&#xff01; 目录 cp指令(复制) mv指令(剪切) nano指令 cat指令(打印文件内容) > 输出重定向 >> 追加重定向 < 输入重定向 more指令 less指令(推荐) …

Ueditor 百度强大富文本Springboot 项目集成使用(包含上传文件和上传图片的功能使用)简单易懂,举一反三

Ueditor 百度强大富文本Springboot 项目集成使用 首先如果大家的富文本中不考虑图片或者附件的情况下&#xff0c;只考虑纯文本且排版的情况下我们可以直接让前端的vue来继承UEditor就可以啦。但是要让前端将那几个上传图片和附件的哪些功能给阉割掉&#xff01; 然后就是说如…

Spring Batch教程(三)示例:从mysql中读取数据写入文本和从多个文本中读取内容写入mysql

Spring batch 系列文章 Spring Batch教程&#xff08;一&#xff09; 简单的介绍以及通过springbatch将xml文件转成txt文件 Spring Batch教程&#xff08;二&#xff09;示例&#xff1a;将txt文件转成xml文件以及读取xml文件内容存储到数据库mysql Spring Batch教程&#xff…

P8605 [蓝桥杯 2013 国 AC] 网络寻路 (dfs+理解题意)

题意&#xff1a;找一条四边的路径&#xff0c;保住中间两个节点编号只能出现一次&#xff08;起点&#xff08;首&#xff09;和终点&#xff08;未&#xff09;可以一样&#xff09; else{if(k3&&toBegin){//首未一样的情况&#xff08;前提是未已经是四边的最后一点…

HTML的表格应用

HTML 中的表格用于在网页上展示和组织数据。表格由行和列组成&#xff0c;每个单元格可以包含文本、图像或其他 HTML 元素。下面是一些常用的 HTML 表格标签和属性的应用示例&#xff1a; <table> 标签: 定义表格的起始和结束标记。所有的表格元素应该放在这对标签之间。…