具代表性的面試主題

後端面試:405 Method Not Allowed 為什麼必須回傳 Allow?

後端中等
Offer.cc 編輯團隊發佈 更新

題幹

檔案 API 只開放 GET 與 HEAD,卻收到 POST 或 DELETE 時,為什麼回傳 405?如何產生 Allow、設計錯誤本文並驗證閘道鏈路?

題目

你維護一個檔案 API:GET /v1/files/:id 可以讀取檔案,客戶端卻對同一個資源送出 POSTDELETE。面試官要求你設計回應,並說明 405、404、403、OPTIONS 與 CORS 預檢的差異。請給出路由判定、Allow 標頭、錯誤本文、測試與上線策略。

背景與限制

  • 資源路由已經匹配到具體檔案,但目前只開放 GETHEAD
  • 客戶端可能因 SDK 版本不一致而誤用方法,代理層也可能改寫或攔截請求。
  • API 需要讓呼叫端能診斷,同時不能把未啟用的方法誤報成可用。
  • 若資源是否存在本身敏感,團隊可以採用一致的 404 隱藏策略,但必須在介面契約中說清楚。

面試官考察點

先區分資源匹配與方法分派

先完成主機、路徑、版本與資源識別碼的匹配,再查詢該資源允許的方法集合。路徑不存在時回傳 404;路徑存在但方法不在集合中時回傳 405。授權檢查仍應遵循系統安全策略:請求者無權存取可以回傳 403,不能把所有權限失敗都偽裝成 405。

405 必須帶 Allow

405 表示伺服器認得請求方法,但目標資源不支援它。回應必須帶上 Allow,列出該資源目前支援的方法,例如:

http
HTTP/1.1 405 Method Not Allowed
Allow: GET, HEAD, OPTIONS
Content-Type: application/problem+json

{"type":"about:blank","title":"Method Not Allowed","status":405,"detail":"Use one of the methods listed in Allow."}

Allow 描述資源能力;它與 CORS 的 Access-Control-Allow-Methods 不是同一個標頭。後者只參與瀏覽器跨來源策略,不能取代 405 的方法契約。

OPTIONS 要獨立建模

OPTIONS 可用來詢問通訊選項,瀏覽器 CORS 預檢還會帶上 OriginAccess-Control-Request-Method。預檢是否成功取決於 CORS 回應標頭與驗證策略;不能看到 OPTIONS 就把所有請求改成 405,也不能把 Allow 當成 CORS 授權清單。

回答前需要釐清的問題

  • 資源是否確實存在?不存在時按 404 處理;若安全策略隱藏存在性,要先確認是否統一回傳 404。
  • 允許的方法是否隨租戶、資源狀態或 API 版本變化?答案會決定 Allow 的產生上下文與快取鍵。
  • 閘道是否會改寫未知方法,或由誰負責產生 Allow?答案會決定排查邊界與唯一資料來源。

30 秒回答框架

「路徑已經匹配,但請求方法不在該資源的能力集合中,所以回傳 405,並在 Allow 列出目前真正支援的方法。路徑不存在才是 404,權限拒絕依策略是 403;OPTIONS 與 CORS 預檢則有另一套回應標頭。最後我會用方法矩陣、真實閘道鏈路與灰度指標驗證。」

分步驟深入解答

把每條資源路由的允許方法定義成可稽核的註冊表,並讓路由器以同一份註冊表完成分派與產生 Allow。對 POST /v1/files/123,若資源存在且 POST 未註冊,回傳 405;對不存在的 123 回傳 404;對已匹配但沒有存取權限的請求,依授權策略回傳 403。HEAD 通常應與 GET 的可讀能力保持一致,但仍要以框架實際行為為準。

錯誤本文應給出穩定的狀態、標題與可行動說明,避免洩漏堆疊或內部路由細節。Allow 只列實際啟用的方法,灰度期間不要提前宣傳尚未部署的寫入能力。若採用隱藏資源存在性的安全策略,應把 404 與 405 的選擇、日誌欄位和客戶端重試行為寫入契約。

高品質示範回答

「我會先讓路由器確認檔案資源是否存在,再從唯一的方法註冊表做分派。對存在的檔案收到未註冊的 POST,回傳 405,並把 GET, HEAD 以及實際支援的 OPTIONS 寫進 Allow;不存在的檔案回傳 404,已匹配但無權限則依授權策略回傳 403。CORS 預檢使用 Access-Control-Allow-Methods,不能拿它取代 Allow。閘道與應用程式只保留一個產生來源,契約測試逐項檢查狀態碼和方法集合,灰度時監控 405 依方法的分布。」

常見錯誤

  • 把「路徑存在但方法不支援」寫成 404,呼叫端無法判斷是 URL 錯誤還是方法錯誤。
  • 回傳 405 卻遺漏 Allow,客戶端無法自動發現可用方法,也違反 HTTP 語義。
  • Access-Control-Allow-Methods 取代 Allow,混淆 HTTP 能力和瀏覽器跨來源授權。
  • 把驗證失敗統一改成 405,導致安全稽核、監控和客戶端處理失真。
  • 由閘道產生一套 Allow、應用程式產生另一套 Allow,代理快取後出現不一致。

錯誤表現與修正

把 405 當成通用失敗碼、遺漏 Allow,或把 CORS 標頭當成 Allow,都會讓呼叫端無法採取下一步。修正方法是先完成資源匹配,再由同一份方法註冊表產生狀態碼與標頭,並為 404、403、405 和預檢分別建立測試。

生產化實作

路由與代理協作

讓閘道透傳應用程式的 405 和 Allow,或明確由閘道統一產生並禁止應用程式重複覆寫。每個版本維護方法矩陣,記錄快取、冪等性、驗證和冪等重試要求。若代理把未知方法降級成 GET,應先修正代理策略,否則應用程式永遠看不到真實方法。

可觀測性與相容性

記錄請求方法、正規化路徑、路由版本、回應狀態和最終 Allow 集合,不記錄敏感檔案內容。客戶端收到 405 後應停止對同一方法盲目重試,改用契約允許的方法或升級 SDK。對舊客戶端可先在日誌和文件中觀察誤用,再透過版本化變更逐步收緊。

驗證清單

契約測試

為每個資源建立方法矩陣,至少涵蓋:已註冊方法成功、未註冊方法回傳 405、路徑不存在回傳 404、授權拒絕回傳 403,以及 Allow 與實際路由一致。斷言狀態碼、標頭方法集合、內容類型和錯誤本文欄位。

整合與回歸

透過真實 HTTP 客戶端驗證閘道、負載平衡和應用程式的組合行為;單獨驗證 OPTIONS 與 CORS 預檢,檢查 Access-Control-Allow-Methods 不會取代 Allow。灰度期間對 405 比例、依方法分布和錯誤本文解析失敗率設定告警。

追問及應對

什麼時候可以回傳 404 而非 405?

當路徑確實不存在,或安全策略要求隱藏資源存在性時,可以回傳 404。關鍵是對同一類資源保持一致,並在文件、日誌與客戶端策略中說明,避免同一介面在不同節點隨機回傳 404 或 405。

Allow 是否一定要包含 OPTIONS?

只有該資源實際接受 OPTIONS 時才列出。框架自動處理 OPTIONS 時,應確認它的回應和應用程式路由契約一致;不能為了「看起來完整」加入未實作的方法。

如何處理動態能力?

若方法能力隨租戶、版本或資源狀態變化,產生 Allow 時必須使用目前請求上下文,並讓快取鍵包含影響能力的維度。較穩妥的做法是減少中介層快取 405,或明確設定合適的快取策略。

評分標準

  • 語義準確:能說明 405 的觸發條件和 Allow 的強制性。
  • 邊界清楚:能區分 404、403、OPTIONS、CORS 與資源安全隱藏策略。
  • 實作可落地:路由註冊表、代理協作、錯誤本文和可觀測性具體。
  • 驗證完整:涵蓋方法矩陣、真實 HTTP 鏈路、灰度指標與回歸。
  • 風險意識:不誤報方法、不洩漏內部細節、不讓閘道與應用程式產生分歧。

參考資料

  • MDN:405 Method Not Allowed
  • MDN:Allow header
  • Postman:HTTP Error 405
  • JustAcademy:REST API interview questions

面試作答要點

先說「資源已匹配、方法不支援、回傳 405」,再給出 Allow 的實際集合;接著區分 404、403、OPTIONS 和 CORS,最後補上方法矩陣、代理一致性與測試證據。

一句話總結

405 負責表達資源的方法不匹配,Allow 負責告訴客戶端目前可用方法,兩者共同構成可診斷的 HTTP 契約。

公開來源

同類題目