Nginx

nginx’proxy_pass 發出的請求失敗,但如果手動完成,它們會成功

  • November 5, 2019

我正在代理位於第二個 nginx 實例(向 PHP-FPM 發送請求)後面的 WP 部落格。

如果我從瀏覽器或 HTTPie 等命令行發出請求,則請求成功。例如

$ http http://x.y.z.w/test-page/
HTTP/1.1 200 OK
...

但是,proxy_pass在我的電腦上使用 nginx 實例時返回 404。在查看 WP 的部落格 nginx 日誌後,我看到以下內容:

<my-ip> - - [05/Nov/2019:09:53:37 +0000] "GET /test-page/ HTTP/1.1" 404 196 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.87 Safari/537.36"
<my-ip> - - [05/Nov/2019:09:53:43 +0000] "GET /test-page/ HTTP/1.1" 200 21317 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.87 Safari/537.36"

怎麼可能一切看起來都一樣,但伺服器首先返回 404,然後返回 200?一定有區別。我還檢查了 HTTPie 發送的標頭。沒有什麼不尋常的:

GET /test-page/ HTTP/1.1
Accept: */*
Accept-Encoding: gzip, deflate
Connection: keep-alive
Host: x.y.z.w
User-Agent: HTTPie/0.9.9

這是此測試的最小 nginx 配置:

events {
   worker_connections                 5000;
   multi_accept                       on;
   use                                epoll;
}

http {
   log_format                          timed_combined '$remote_addr - $remote_user [$time_local] ' '"$request" $status $body_bytes_sent ' '"$http_referer" "$http_user_agent" ' '$request_time';

   access_log                           /var/log/nginx/access.log timed_combined;
   error_log                            /var/log/nginx/error.log warn;

   resolver                             1.1.1.1 8.8.8.8 8.8.4.4 valid=60s;
   resolver_timeout                     15s;

   index                                index.html;

   upstream front-wp {
       server x.y.z.w:80;
   }

   server {
       listen 80;

       location /wp-content/ {
           proxy_pass http://front-wp;
           proxy_http_version 1.1;
           proxy_set_header X-Real-IP $remote_addr;
           proxy_set_header Host $host;
           proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
       }

       location = /test-page/ {
           proxy_pass http://front-wp;
           proxy_http_version 1.1;
           proxy_set_header X-Real-IP $remote_addr;
           proxy_set_header Host $host;
           proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
       }
   }
}

這個問題真的讓我抓狂。

可能是伺服器在x.y.z.w使用基於名稱的虛擬主機,並且兩個請求由不同的虛擬主機處理。

URLhttp://x.y.z.w/test-page/設置x.y.z.w用於選擇其中一個虛擬主機的 Host 標頭值。

通過反向代理的請求將 Host 標頭值設置$host為用於選擇另一個虛擬主機(當 Host 值未知時可能是預設主機)。

要確認這一點,請嘗試:

proxy_set_header Host "x.y.z.w";

這應該使兩個請求足夠相似以由同一虛擬主機處理。

x.y.z.w如果需要不同的行為,您將需要查看伺服器的配置。

引用自:https://serverfault.com/questions/990629