400 Bad Request
用法
收到 400 Bad Request 错误时,客户端有责任检查消息体以进一步了解失败原因。服务器会返回足够的细节,供客户端纠正问题。导致 400 Bad Request 响应的常见原因包括:
出现这些错误时,客户端可以尝试仔细核对 URL、清除浏览器 Cookie,或在重新传输前压缩过大的文件。
注意
400 错误属于客户端错误(请求畸形),而 500 错误属于服务器故障(服务器在处理一个有效请求时出错)。400 不是临时性的。重试相同的请求会得到相同的错误。客户端必须先修复请求再重试。注入畸形头的浏览器扩展或广告软件是导致意外 400 错误的常见原因。禁用扩展有助于诊断问题。
SEO 影响
像 Google 这样的搜索引擎不会索引返回 400 状态的 URL。此前已被索引、如今返回该状态码的 URL 会从搜索结果中移除。返回此状态码的页面不会消耗抓取预算。
示例
客户端请求一个路径中包含花括号字符的资源。这些字符在 URL 中无效,因此服务器返回 400 Bad Request。
请求
GET /index{15}.html HTTP/1.1
Host: example.com
响应
HTTP/1.1 400 Bad Request
Content-Type: text/html; charset=UTF-8
Content-Length: 131
<html>
<head>
<title>Malformed URL</title>
</head>
<body>
<p>Invalid characters in HTTP request</p>
</body>
</html>
如何修复
400 Bad Request 意味着服务器因客户端侧的格式问题而拒绝了请求。
检查 URL 是否存在编码错误。花括号、空格或非 ASCII 字符等特殊字符需要进行百分号编码。检查完整的请求路径和查询字符串。用校验工具检查 URL 以发现非法字节序列。
校验请求头。畸形的 Host 头、过大的 Cookie 头或缺失的必需头都会触发此错误。将请求头与 API 规范进行对照。使用浏览器开发者工具(Network 标签页)或 curl -v 来检查随请求发送的原始头。
检查请求体是否存在语法错误。无效的 JSON、损坏的表单编码,或 Content-Type 头与实际消息体格式不匹配,都会导致请求被拒绝。发送前用 linter 校验 JSON 载荷。
清除浏览器缓存和 Cookie。损坏或过期的 Cookie 会产生畸形的请求头。过大的 Cookie 值超出服务器缓冲区限制是一个常见诱因。清除已存储的数据后重试。
核对 Content-Length 与实际消息体大小是否一致。声明的字节数与实际传输的字节数不匹配会导致 bad request 响应。
检查服务端的大小限制。当请求头超出 large_client_header_buffers 配置的缓冲区(默认为 4 个 8 KB 的缓冲区)时,nginx 会以 400 拒绝过大的请求头。在 nginx.conf 中增大该值:
large_client_header_buffers 4 16k;
Apache 强制执行 LimitRequestFieldSize(默认 8190 字节)和 LimitRequestLine。在服务器配置或虚拟主机中调高这些值:
LimitRequestFieldSize 16384
LimitRequestLine 16384
启用调试日志以定位确切原因。nginx 会在 info 级别记录拒绝原因。将 error_log 设为 info 并查看 /var/log/nginx/error.log。Apache 会在 LogLevel info 级别的错误日志中记录出问题的头名称。
检查反向代理的头转发。当 nginx 或 Apache 作为反向代理运行时,错误设置的 Host、X-Forwarded-For 或 X-Real-IP 头会导致后端拒绝请求。核实 proxy_set_header 指令传递的值是否有效。
代码参考
.NET
HttpStatusCode.BadRequest
Rust
http::StatusCode::BAD_REQUEST
Rails
:bad_request
Go
http.StatusBadRequest
Symfony
Response::HTTP_BAD_REQUEST
Python3.5+
http.HTTPStatus.BAD_REQUEST
Java
java.net.HttpURLConnection.HTTP_BAD_REQUEST
Apache HttpComponents Core
org.apache.hc.core5.http.HttpStatus.SC_BAD_REQUEST
Angular
@angular/common/http/HttpStatusCode.BadRequest