Nginx 405 Method Not Allowed 錯誤問題與解決

在 Docker 容器化的 SPA 應用中,我們遇到了 API 請求出現 405 Method Not Allowed 錯誤的問題。

問題原因

這個問題出現的原因是與我們的 Nginx 設定有關:

  1. 我們使用了 Nginx 作為網頁伺服器

  2. 為了解決 SPA 重新整理頁面時的 404 問題,在 nginx.conf 中設定了:

location / {
    try_files $uri $uri/ /index.html;
}
  1. 當我們發送 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 的兩個重要功能:

  1. URL 重寫(URL rewriting):通過 try_files 指令讓 SPA 的前端路由正常工作

  2. 反向代理(Reverse proxy):通過 proxy_pass 指令將 API 請求轉發到後端服務

在 Docker Compose 環境中,服務之間可以使用服務名稱(如 server)作為主機名來通訊,這是因為 Docker Compose 會自動設定內部 DNS 解析。

檢查與測試

設定完成後,可以透過以下方式驗證:

  1. 前端 SPA 路由:瀏覽器導航並重新整理頁面,確認不再出現 404 錯誤

  2. API 請求:嘗試登入或其他 API 操作,確認不再出現 405 錯誤

若一切正常,表示 Nginx 設定已經正確處理了前端路由和 API 請求的需求。

Last updated