問題起因是利用Nginx做反向代理的時候,需要訪問如下鏈接
http://192.168.14.141/iserver/services/3D-0524hd/rest/realspace/datas/0524hd/data/path/Tile_+003_+011/Tile_+003_+011_L5_00003.s3m
其中192.168.14.141被反向代理到了192.168.14.141:8090
實際請求的時候返回404,通過查看服務日誌,發現服務器收到的Nginx請求確實是這個鏈接(注意後半部分):
http://192.168.14.141/iserver/services/3D-0524hd/rest/realspace/datas/0524hd/data/path/Tile_+003_+011/Tile_+003_+011_L5_00003.s3m
如果我直接請求8090端口,服務器實際收到的請求是下面這樣:
http://192.168.14.141/iserver/services/3D-0524hd/rest/realspace/datas/0524hd/data/path/Tile_%2B003_%2B011/Tile_%2B003_%2B011_L5_00003.s3m
’+’ 號應該被編碼未‘%2B’,但是Nginx沒有將其編碼,導致請求404
手動將+號寫成%2B請求到Nginx, Nginx請求目標服務器時還是以+號的形式請求。
解決辦法:手動處理一下編碼的問題
location /server {
set $modified_uri $request_uri;
if ($modified_uri ~ "^/([\w]{2})(/.*)") {
set $modified_uri $1;
}
proxy_pass http://192.168.14.141:8090$modified_uri;
}
詳見:https://stackoverflow.com/questions/31266629/nginx-encoding-normalizing-part-of-uri
附官方文檔:
If proxy_pass is specified without a URI, the request URI is passed to the server in the same form as sent by a client when the original request is processed, or the full normalized request URI is passed when processing the changed URI:
如果proxy_pass沒有指定具體的URI,那麼請求Nginx的URI將原封不動的被轉發到目標服務器。 即便是手動將+號編碼,但是Nginx貌似會對其進行解碼,最後發送出去的請求仍然是沒有編碼的。