405 Method Not Allowed
用法
收到 405 Method Not Allowed 错误时,客户端明白资源存在,但所指定的方法不被允许。作为响应的一部分,服务器会发送一个 Allow 头,列出该资源当前支持的方法。
SEO 影响
像 Google 这样的搜索引擎不会索引返回 405 状态的 URL。此前已被索引、如今返回该状态码的 URL 会从搜索结果中移除。
示例
客户端尝试对一个只读资源执行 DELETE。服务器返回 405 Method Not Allowed,并包含 Allow 头,表明仅允许 GET、HEAD 和 OPTIONS。
请求
DELETE /policies.pdf HTTP/1.1
Host: example.com
响应
HTTP/1.1 405 Method Not Allowed
Allow: GET, HEAD, OPTIONS
Content-Type: text/html
Content-Length: 157
<html>
<head>
<title>Operation Not Permitted</title>
</head>
<body>
<p>This resource is read-only and cannot be
deleted.</p>
</body>
</html>
如何修复
405 Method Not Allowed 意味着资源存在,但不支持请求中所用的 HTTP 方法。
检查响应中的 Allow 头。服务器会包含该头,列出资源允许的每一个方法。切换到列出的某个方法。使用 curl -I
切换到正确的方法。一个常见错误是向只读端点发送 POST,或向提交端点发送 GET。使方法与 API 文档中描述的操作相匹配。表单提交在未将 method 属性设为 post 时默认为 GET。
核实 API 端点文档。REST API 为每个资源路径定义了特定的方法。确认路径和方法的组合是有效的。在许多框架中,/api/users 与 /api/users/ 之间的末尾斜杠差异会路由到不同的处理程序,其中一个路径接受该方法而另一个不接受。
检查服务器配置中的方法限制。Web 服务器指令按 location 限制允许的方法。在 Apache 中,
<LimitExcept GET HEAD OPTIONS>
Require all denied
</LimitExcept>
在 nginx 中,limit_except 指令可实现相同效果:
location /api {
limit_except GET POST {
deny all;
}
}
调整这些指令以允许预期的方法。
处理 CORS 预检请求。跨域请求会在实际方法之前触发一次 OPTIONS 预检。服务器必须以正确的 Access-Control-Allow-Methods 头响应 OPTIONS,列出允许的方法。缺失或不完整的 CORS 配置会使预检返回 405。在 nginx 中:
add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS";
审查应用框架的路由。Web 框架(Django、Rails、Express、Spring)只为显式声明的方法注册路由。缺少对应所请求方法的路由装饰器或控制器动作会产生 405。确认路由定义与预期的 HTTP 方法相匹配。
检查静态文件服务器的干扰。nginx 默认提供静态文件服务,并会拒绝对静态资源的 POST 请求。当 POST 本应发往应用后端时,核实 location 块会将请求路由到上游应用而非静态文件处理程序。
代码参考
.NET
HttpStatusCode.MethodNotAllowed
Rust
http::StatusCode::METHOD_NOT_ALLOWED
Rails
:method_not_allowed
Go
http.StatusMethodNotAllowed
Symfony
Response::HTTP_METHOD_NOT_ALLOWED
Python3.5+
http.HTTPStatus.METHOD_NOT_ALLOWED
Java
java.net.HttpURLConnection.HTTP_BAD_METHOD
Apache HttpComponents Core
org.apache.hc.core5.http.HttpStatus.SC_METHOD_NOT_ALLOWED
Angular
@angular/common/http/HttpStatusCode.MethodNotAllowed