Nginx 405 Method Not Allowed 錯誤問題與解決
在 Docker 容器化的 SPA 應用中,我們遇到了 API 請求出現 405 Method Not Allowed 錯誤的問題。
問題原因
這個問題出現的原因是與我們的 Nginx 設定有關:
我們使用了 Nginx 作為網頁伺服器
為了解決 SPA 重新整理頁面時的 404 問題,在 nginx.conf 中設定了:
location / {
try_files $uri $uri/ /index.html;
}
當我們發送 API 請求(例如
POST /api/users/login
)時:Nginx 收到請求,套用了上述的
try_files
規則Nginx 嘗試尋找
/api/users/login
這個檔案但因為請求方法是 POST,而不是用於取得檔案的 GET
Nginx 回應 405 Method Not Allowed 錯誤
簡單來說,Nginx 誤把 API 請求當成靜態檔案請求來處理,導致方法不匹配的錯誤。
解決方案
由於我們的 API 路徑都是以 /api
開頭,可以在 nginx.conf 中添加一個特定的 location 區塊來處理這些請求:
location /api {
proxy_pass http://server:3000;
}
這個設定的作用是:
當 Nginx 收到以
/api
開頭的請求時它不會嘗試查找檔案,而是將請求代理(proxy)到
http://server:3000
這裡的
server
是指 docker-compose.yml 中定義的後端服務名稱3000
是後端服務暴露的連接埠
完整的 nginx.conf 設定
結合 SPA 路由和 API 代理的完整 nginx.conf 檔案應該如下:
server {
listen 80;
server_name localhost;
root /usr/share/nginx/html;
index index.html;
# 處理前端 SPA 路由
location / {
try_files $uri $uri/ /index.html;
}
# 處理 API 請求
location /api {
proxy_pass http://server:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
技術說明
這裡使用了 Nginx 的兩個重要功能:
URL 重寫(URL rewriting):通過
try_files
指令讓 SPA 的前端路由正常工作反向代理(Reverse proxy):通過
proxy_pass
指令將 API 請求轉發到後端服務
在 Docker Compose 環境中,服務之間可以使用服務名稱(如 server
)作為主機名來通訊,這是因為 Docker Compose 會自動設定內部 DNS 解析。
檢查與測試
設定完成後,可以透過以下方式驗證:
前端 SPA 路由:瀏覽器導航並重新整理頁面,確認不再出現 404 錯誤
API 請求:嘗試登入或其他 API 操作,確認不再出現 405 錯誤
若一切正常,表示 Nginx 設定已經正確處理了前端路由和 API 請求的需求。
Last updated