1. 程式人生 > 實用技巧 >如何解決 Nginx 埠對映到外網後訪問地址埠丟失的問題

如何解決 Nginx 埠對映到外網後訪問地址埠丟失的問題

1. 問題說明


一個手機h5頁面的專案,使用nginx(監聽80埠)進行訪問,內網訪問的地址是192.168.12.125/h5,訪問正常,nginx中的配置如下:

#微信H5頁面訪問
location /h5 {
        alias /home/run/web/front;
        index h5index.html;
        break;
}

使用curl檢視的資訊如下:

root@ubuntu:~# curl -v 192.168.12.125/h5
*   Trying 192.168.12.125...
* Connected to 192.168.12.125 (192.168.12.125) port 80 (#0)
> GET /h5 HTTP/1.1
> Host: 192.168.12.125
> User-Agent: curl/7.47.0
> Accept: */*
> 
< HTTP/1.1 301 Moved Permanently
< Server: nginx
< Date: Mon, 25 Nov 2019 02:29:54 GMT
< Content-Type: text/html
< Transfer-Encoding: chunked
< Connection: keep-alive
< Location: http://192.168.12.125/h5/
< Access-Control-Allow-Origin: *
< Access-Control-Allow-Methods: GET,OPTIONS,PUT,DELETE
< Access-Control-Allow-Credentials: true
< Access-Control-Allow-Headers: Authorization,DNT,User-Agent,Keep-Alive,Content-Type,accept,origin,X-Requested-With
< 
<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 192.168.12.125 left intact

可以看到在訪問的時候沒有在uri的最後新增/,但是nginx會自動新增一個/,並且返回一個301重定向。如果當前nginx監聽的是80埠,這個重定向行為不會影響頁面的訪問。但是如果nginx監聽的是其他非80埠,或者是將nginx的80埠對映至外網的其他非80埠的時候,頁面訪問就會出現問題,例如將192.168.12.125伺服器的80埠對映至公網IP地址 35.110.65.81:8888 埠並使用35.110.65.81:8888/h5進行訪問,會發現地址被重定向為 35.110.65.81/h5/ 並且頁面無法訪問,使用curl檢視資訊如下:

[root@iZmkx0kvsmpmfvZ ~]# curl -v http://35.110.65.81:8888/h5
* About to connect() to 35.110.65.81 port 8888 (#0)
*   Trying 35.110.65.81... connected
* Connected to 35.110.65.81 (35.110.65.81) port 8888 (#0)
> GET /h5 HTTP/1.1
> User-Agent: curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.21 Basic ECC zlib/1.2.3 libidn/1.18 libssh2/1.4.2
> Host: 35.110.65.81:8888
> Accept: */*
> 
< HTTP/1.1 301 Moved Permanently
< Server: nginx
< Date: Mon, 25 Nov 2019 02:14:57 GMT
< Content-Type: text/html
< Location: http://35.110.65.81/h5/
< Transfer-Encoding: chunked
< Connection: keep-alive
< Access-Control-Allow-Origin: *
< Access-Control-Allow-Methods: GET,OPTIONS,PUT,DELETE
< Access-Control-Allow-Credentials: true
< Access-Control-Allow-Headers: Authorization,DNT,User-Agent,Keep-Alive,Content-Type,accept,origin,X-Requested-With
< 
<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 35.110.65.81 left intact
* Closing connection #0

2. 解決辦法


對於這個問題的處理辦法是在nginx中配置重寫規則來新增埠資訊,新增的配置如下:

#微信H5頁面訪問
location /h5 {
        if (-d $request_filename) {
                rewrite [^/]$ $scheme://$http_host$uri/ permanent;
        }
        alias /home/run/web/front;
        index h5index.html;
        break;
}

配置完成後重啟nginx,並且使用curl進行測試,顯示的資訊如下:

[root@iZmkx0kvsmpmfvZ ~]# curl -v http://35.110.65.81:8888/h5
* About to connect() to 35.110.65.81 port 8888 (#0)
*   Trying 35.110.65.81... connected
* Connected to 35.110.65.81 (35.110.65.81) port 8888 (#0)
> GET /h5 HTTP/1.1
> User-Agent: curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.21 Basic ECC zlib/1.2.3 libidn/1.18 libssh2/1.4.2
> Host: 35.110.65.81:8888
> Accept: */*
> 
< HTTP/1.1 301 Moved Permanently
< Server: nginx
< Date: Mon, 25 Nov 2019 02:16:03 GMT
< Content-Type: text/html
< Transfer-Encoding: chunked
< Connection: keep-alive
< Location: http://35.110.65.81:8888/h5/
< Access-Control-Allow-Origin: *
< Access-Control-Allow-Methods: GET,OPTIONS,PUT,DELETE
< Access-Control-Allow-Credentials: true
< Access-Control-Allow-Headers: Authorization,DNT,User-Agent,Keep-Alive,Content-Type,accept,origin,X-Requested-With
< 
<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 35.110.65.81 left intact
* Closing connection #0

可以看到訪問後的location地址為35.110.65.81:8888/h5/,頁面也可以正常訪問。