後端面試:405 Method Not Allowed 為什麼必須回傳 Allow?
題目
你維護一個檔案 API:GET /v1/files/:id 可以讀取檔案,客戶端卻對同一個資源送出 POST 或 DELETE。面試官要求你設計回應,並說明 405、404、403、OPTIONS 與 CORS 預檢的差異。請給出路由判定、Allow 標頭、錯誤本文、測試與上線策略。
背景與限制
- 資源路由已經匹配到具體檔案,但目前只開放
GET與HEAD。 - 客戶端可能因 SDK 版本不一致而誤用方法,代理層也可能改寫或攔截請求。
- API 需要讓呼叫端能診斷,同時不能把未啟用的方法誤報成可用。
- 若資源是否存在本身敏感,團隊可以採用一致的 404 隱藏策略,但必須在介面契約中說清楚。
面試官考察點
先區分資源匹配與方法分派
先完成主機、路徑、版本與資源識別碼的匹配,再查詢該資源允許的方法集合。路徑不存在時回傳 404;路徑存在但方法不在集合中時回傳 405。授權檢查仍應遵循系統安全策略:請求者無權存取可以回傳 403,不能把所有權限失敗都偽裝成 405。
405 必須帶 Allow
405 表示伺服器認得請求方法,但目標資源不支援它。回應必須帶上 Allow,列出該資源目前支援的方法,例如:
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 預檢還會帶上 Origin 與 Access-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 契約。