Nginx 重定向時(shí)獲取域名的方法示例
TL;DR
如果你在處理 Nginx 重定向時(shí)要獲取原請(qǐng)求的域名(比如 HTTP 到 HTTPS),請(qǐng)用 $host 而不是 $server_name 。
問(wèn)題和解決方案
今天碰到一個(gè)問(wèn)題,服務(wù)器上一個(gè)子域名的請(qǐng)求重定向到另一個(gè)子域名上面去了。查了一段時(shí)間發(fā)現(xiàn)這個(gè)問(wèn)題只有在 HTTP 到 HTTPS 跳轉(zhuǎn)的時(shí)候才會(huì)發(fā)生。大概是這樣:
從 HTTP 的 sub2 子域名跳轉(zhuǎn)到 HTTPS 的 sub1 子域名
http://sub2.example.com/more_things -> https://sub1.example.com/more_things
我用的 Nginx ,當(dāng)初為了讓 HTTP 請(qǐng)求跳轉(zhuǎn)到同名的 HTTPS 請(qǐng)求,配置如下:
http {
server {
listen 80;
server_name sub1.example.com sub2.example.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl spdy;
server_name sub1.example.com sub2.example.com;
# ...
}
}
因?yàn)?301 是永久重定向,某些瀏覽器的緩存會(huì)記住重定向,下次訪問(wèn)原地址就會(huì)直接向新地址發(fā)請(qǐng)求,所以這個(gè)問(wèn)題在瀏覽器里面不一定重現(xiàn)得了(包括 Chrome 的 Incognito Window),能每次完整重現(xiàn)的方式只有 curl 。
$ curl -I http://sub2.example.com/ HTTP/1.1 301 Moved Permanently Server: nginx/1.9.3 (Ubuntu) Date: Tue, 23 Feb 2016 06:06:30 GMT Content-Type: text/html Content-Length: 193 Connection: keep-alive Location: https://sub1.example.com/
查了一下,發(fā)現(xiàn)問(wèn)題出在 $server_name 變量上。這個(gè)變量會(huì)始終返回 server_name 中第一個(gè)名字。這里其實(shí)應(yīng)該用 $host 變量。修改后的配置如下:
http {
server {
listen 80;
server_name sub1.example.com sub2.example.com;
return 301 https://$host$request_uri;
}
}
$host 變量會(huì)按照以下優(yōu)先級(jí)獲取域名:
- Request-Line 中的域名信息。Request-Line 包含 method, uri 和 HTTP 版本。
- 請(qǐng)求頭信息中的 "Host" 。
- Nginx 中匹配的 server_name 配置。
這幾乎可以保證在任何環(huán)境下正確地得到域名。如果是同域名下的重定向最好都用 $host 。
參考資料
Nginx Wiki - $host
Nginx 官方文檔。其中對(duì) $host 講的比較詳細(xì),但 $server_name 只是一筆帶過(guò)。
StackOverflow - What is the difference between Nginx variables $host, $http_host, and $server_name?
StackOverflow 上關(guān)于三個(gè)變量區(qū)別的討論。里面提到了為什么 $host 是適用于所有場(chǎng)景的唯一選擇。
HTTP/1.1 : Request-Line
HTTP/1.1 規(guī)范中對(duì) Request-Line 的描述。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Nginx暴露出請(qǐng)求的真實(shí)IP的問(wèn)題
在工作中,經(jīng)常會(huì)用用戶實(shí)際請(qǐng)求的IP地址,本文主要介紹了Nginx暴露出請(qǐng)求的真實(shí)IP的問(wèn)題,具有一定的參考價(jià)值,感興趣的可以了解一下2023-10-10
詳解nginx實(shí)現(xiàn)ssl反向代理實(shí)戰(zhàn)
本篇文章主要介紹了nginx實(shí)現(xiàn)ssl反向代理實(shí)戰(zhàn),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-01-01
nginx+tomcat 通過(guò)域名訪問(wèn)項(xiàng)目的實(shí)例
這篇文章主要介紹了nginx+tomcat 通過(guò)域名訪問(wèn)項(xiàng)目的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-05-05
nginx支持.htaccess文件實(shí)現(xiàn)偽靜態(tài)的方法分享
這篇文章主要介紹了nginx支持.htaccess文件實(shí)現(xiàn)偽靜態(tài)的方法分享,需要的朋友可以參考下2015-01-01
詳解Nginx的核心配置模塊中對(duì)于請(qǐng)求體的接受流程
這篇文章主要介紹了詳解Nginx的核心配置模塊中對(duì)于請(qǐng)求體的接受流程,包括其丟棄請(qǐng)求的過(guò)程,需要的朋友可以參考下2015-12-12
nginx 1.0.0配ngx_cache_purge實(shí)現(xiàn)高效的反向代理
nginx默認(rèn)安裝就會(huì)帶有反向代理的功能,但想要更好的使用,還得配備frickle.com的ngx_cache_purge模塊,用于清除指定URL的緩存。2011-06-06
Nginx中try_files指令的實(shí)現(xiàn)示例
try_files是Nginx配置中的一個(gè)指令,用于檢查文件是否存在,并根據(jù)存在情況處理請(qǐng)求,本文就來(lái)介紹一下Nginx中try_files指令的實(shí)現(xiàn)示例,感興趣的可以了解一下2024-10-10

