Nginx中處理重定向端口丟失問題

前言

nginx有時候并不像apache那樣智能,對于redirect location的處理尤為慘淡,幾乎只能用戶手工處理非標準端口的問題。

比如因為種種原因,nginx并不能監(jiān)聽在80端口,或者外部通過NAT方式將請求丟給nginx,外部地址并不是標準http(s)端口,此時nginx并不能美好的處理這些重定向。發(fā)生重定向的時候會丟失端口。

比如以下兩種參考范例:

#反向代理
listen 81 default_server;
set $TOMCAT_HOME /var/lib/tomcat7;

location / {
    root $TOMCAT_HOME/webapps/ROOT;
    proxy_pass http://127.0.0.1:8080/;
    proxy_set_header Host             $host;
    proxy_set_header X-Real-IP        $remote_addr;  
    proxy_set_header X-Forwarded-For  $proxy_add_x_forwarded_for;
}
# 訪問/data的時候,瀏覽器發(fā)出請求`http://xxx.com/data`
# 未查詢到/data文件,url被重定向到`http://xxx.com/data/`目錄
listen 81 default_server;

location /data {
    root /var/data;
}

瀏覽器請求的時候會發(fā)現(xiàn)只要發(fā)生重定向,端口號就會丟失,導(dǎo)致瀏覽器訪問到錯誤的端口。

分別對這兩種情況給出解決方案。

反向代理

這個很容易搞定,那一堆proxy_set_header不知道何時在網(wǎng)上流傳開來的,幾乎國內(nèi)外文檔無一例外都是這個鳥樣子。后來我發(fā)現(xiàn)gitlab-ce這個用非標準端口訪問是沒有問題的,我看了一下gitlab-ce的nginx配置,發(fā)現(xiàn)是這么配置的:

proxy_set_header Host             $http_host;

我又發(fā)現(xiàn)nginx軟件包釋放出的配置文件,發(fā)現(xiàn)里面其實是帶有一個參考文件/etc/nginx/proxy_params

proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;

這里面寫的也是 proxy_set_header Host $http_host;,于是乎直接include,搞定

location / {
    root $TOMCAT_HOME/webapps/ROOT;
    proxy_pass http://127.0.0.1:8080/;
    include proxy_params;
}

沒這個文件就把這些內(nèi)容手工敲到location配置段下。

再細看官方文檔,其實也提及了:

An unchanged “Host” request header field can be passed like this:

  proxy_set_header Host       $http_host;

訪問目錄沒帶/

這個比較棘手,比如$document_root存在data/index.html文件,但是訪問的時候使用的是/data最后沒加/去表示其訪問的是一個目錄,服務(wù)器此時會進行301 Moved Permanently永久重定向處理,但是比較扯的地方在于,如果nginx監(jiān)聽的是非標準端口,這個301返回的Location沒有端口號,導(dǎo)致瀏覽器請求出錯。

用curl可以很明顯的看到這一點:

$ curl -v mydomain:81/data
* Hostname was NOT found in DNS cache
*   Trying *.*.*.*...
* Connected to mydomain (*.*.*.*) port 81 (#0)
> GET /test HTTP/1.1
> User-Agent: curl/7.35.0
> Host: mydomain:81
> Accept: */*
> 
< HTTP/1.1 301 Moved Permanently
* Server nginx is not blacklisted
< Server: nginx
< Date: Wed, 18 Nov 2015 07:39:03 GMT
< Content-Type: text/html
< Content-Length: 178
< Connection: keep-alive
< Location: http://mydomain/data/
< 
<html>
<head><title>301 Moved Permanently</title></head>
<body bgcolor="white">
<center><h1>301 Moved Permanently</h1></center>
<hr><center>nginx</center>
</body>
</html>
* Connection #0 to host mydomain left intact

可以很明顯的看到Location沒有端口號了,這個重定向又和反向代理不一樣。于是遍尋google,最終在stackoverflow的問答中找到了解決方案:

if (-d $request_filename) {
   rewrite [^/]$ $scheme://$http_host$uri/ permanent;
}

通過配置對URL重寫的形式帶上端口號,問題解決。

轉(zhuǎn)載自:http://www.voidcn.com/article/p-nocikewh-bpa.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容