nginx server_name配置多個域名時的坑
server_name 指令詳解
server_name 指令設(shè)置基于域名的虛擬主機,?個ip的服務(wù)器可以配置多個域名。下?這些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允許?個虛擬主機有?個或多個名字,也可以使?通配符"*"來設(shè)置虛擬主機的名字。
server_name指令在接到請求后的匹配順序分別為:
- 1、準(zhǔn)確的server_name匹配,例如:domain.com www.domain.com
- 2、以通配符開始的字符串: .domain.com .domain.com
- 3、以通配符結(jié)束的字符串:www.
- 4、匹配正則表達(dá)式:~^(?.+).domain.com$
nginx將按照1,2,3,4的順序?qū)erver name進(jìn)?匹配,有?項匹配以后就會停?搜索,類似于location指令。
背景
為了區(qū)分線上環(huán)境和測試環(huán)境,我弄了個自己測試專用的域名test.daemoncoder.com,線上環(huán)境的正式域名是www.daemoncoder.com。nginx里的server_name配置改為:
# 只列出了我們關(guān)心的配置,省略了其他無關(guān)部分 server { server_name www.daemoncoder.com test.daemoncoder.com; ... }
但是使用時發(fā)現(xiàn)請求一直報錯,重定向到錯誤頁面,于是開始了問題的定位。
問題的定位
根據(jù)業(yè)務(wù)上報錯時打的日志,定位到請求公共處理的部分里有這么一個判斷:
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 的取值和我們的預(yù)期不一致,nginx是怎么把這個變量傳過來的,需要從 nginx 的 fastcgi_params 配置文件中找一下 SERVER_NAME 的定義:
fastcgi_param SERVER_NAME $server_name;
可以看到 nginx 里的 $server_name 變量就是我們PHP里取的$_SERVER['SERVER_NAME'] 的來源。
問題的原因
通過上面的定位,我們基本可以看到問題的根本原因了(敲黑板,劃重點):
當(dāng)nginx配置里一個server節(jié)點下,server_name配置多個域名時,$server_name變量的值都是配置的第一個。
再回顧下我的 nginx 配置:
# 只列出了我們關(guān)心的配置,省略了其他無關(guān)部分 server { server_name www.daemoncoder.com test.daemoncoder.com; ... }
server_name 結(jié)點有兩個:www.daemoncoder.com 和 test.daemoncoder.com,當(dāng)我用測試域名去訪問頁面的時候,可以匹配到 test.daemoncoder.com 這個域名,所以會根據(jù)當(dāng)前這個server節(jié)點的配置來處理這個請求,但是 nginx 會把 $server_name 的值設(shè)置為當(dāng)前 server 節(jié)點的配置的第一個 server_name,也就是 www.daemoncoder.com。如果配置改為:
server_name test.daemoncoder.com www.daemoncoder.com;
那么用測試域名請求就可以得到期望的值了(但是正式域名就出問題了)。
解決方式
第一種方式就是把配置文件按域名拆分到各自單獨的server節(jié)點下,也就是:
# 省略其他無關(guān)部分 server { server_name www.daemoncoder.com; ... } server { server_name test.daemoncoder.com; ... }
這樣用不同的域名訪問會落到各自對應(yīng)的配置中,解析到的 $server_name 也都是各自的值。
第二種方式是修改 nginx SERVER_NAME 使用 $host 變量, 也就是把
fastcgi_param SERVER_NAME $server_name;
修改為:
fastcgi_param SERVER_NAME $host;
$host變量的解析都是當(dāng)前請求的host,不會受 server_name 是否配置多個域名的影響,這樣我們在PHP里取 $_SERVER['SERVER_NAME'] 取出的值就是實際請求的域名,也可以解決問題(但是代碼里的這個判斷邏輯在測試環(huán)境似乎就沒有意義了,問題不大)。
其他
有多個域名時(server_name other.domain.com www. domain.com;):fastcgi_param SERVER_NAME $server_name ,$server_name 會取值第一個域名(other.domain.com)。
$host 有可能等于 $server_name ,也可能是IP地址(直接通過訪問此優(yōu)先順序取值:請求行中的主機名,或“主機”請求標(biāo)頭字段中的主機名,或與請求匹配的服務(wù)器名。
$1|$2|$3 ...
是nginx在匹配正則時生成的變量,用于捕獲一個正則表達(dá)式括號中匹配的字符串(從左到右依次存儲在$1|$2|$3 ...
中),新值覆蓋舊值,可以使用變量保存需要用到的值:set $pre $1
到此這篇關(guān)于nginx server_name配置多個域名時的坑的文章就介紹到這了,更多相關(guān)nginx server_name配置多個域名內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
詳解Nginx服務(wù)器中配置全站HTTPS安全連接的方法
這篇文章主要介紹了詳解Nginx服務(wù)器中配置全站HTTPS安全連接的方法,其中要點還是在于SSL證書的申請,需要的朋友可以參考下2016-01-01keepalived監(jiān)控nginx進(jìn)程的實現(xiàn)示例
本文主要介紹了keepalived監(jiān)控nginx進(jìn)程的實現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2024-08-08Nginx下Wordpress的永久鏈接實現(xiàn)(301,404等)
經(jīng)過多番測試,終于在nginx下實現(xiàn)了rewrite的功能,WrodPress的永久鏈接終于生效了2012-09-09Nginx 502 Bad Gateway錯誤原因及解決方案
這篇文章主要介紹了Nginx 502 Bad Gateway錯誤原因及解決方案,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-11-11寶塔里nginx自動停止的解決方法(檢測腳本實現(xiàn)每分鐘檢測并自動啟用)
nginx突然停止的原因有多種,這里不列舉,可以排查具體原因,這里主要為大家分享nginx服務(wù)的檢測腳本,達(dá)到自動啟用的實現(xiàn)2025-02-02Nginx、Apache、Lighttpd禁止目錄執(zhí)行php配置示例
這篇文章主要介紹了Nginx、Apache、Lighttpd禁止目錄執(zhí)行php配置示例,本文給出了單個目錄、多個目錄的禁止執(zhí)行PHP的方法,需要的朋友可以參考下2014-09-09Nginx偽靜態(tài)配置和常用Rewrite偽靜態(tài)規(guī)則集錦
偽靜態(tài)是一種可以把文件后綴改成任何可能的一種方法,如果我想把php文件偽靜態(tài)成html文件,這種相當(dāng)簡單的,下面我來介紹nginx 偽靜態(tài)配置方法有需要了解的朋友可參考。2014-06-06