422 Unprocessable Content
用法
422 Unprocessable Content 错误表示服务器理解了请求,但发现其内容在语义上无效。内容类型是能被识别的(否则会返回 415 Unsupported Media Type 错误)。语法也是有效的(否则返回 400 Bad Request 错误更合适)。
当请求包含一段 XML 指令块作为消息体,格式正确且能被服务器理解,但其中存在逻辑错误从而导致服务器端错误时,就会出现此类错误。
注意
在不修改请求体的情况下重试 422 会产生相同的错误。客户端必须先修复校验问题。当 Content-Type 能被识别且语法有效,但业务规则或字段校验拒绝了该数据时,返回 422。
SEO 影响
像 Google 这样的搜索引擎不会索引返回 422 Unprocessable Content 状态的 URL,因此过去已被索引但返回此 HTTP 状态码的 URL 会从搜索结果中移除。
示例
客户端使用一份 XML 文档请求启动任务 #100。该 XML 文档能被服务器识别且语法正确。但服务器中没有 id=100 的任务记录,因此请求无法处理。
请求
POST /requests HTTP/1.1
Host: example.com
Content-Type: application/xml
Content-Length: 101
<?xml version="1.0" encoding="utf-8"?>
<request>
<id>100</id>
<action>start</action>
</request>
响应
HTTP/1.1 422 Unprocessable Content
Content-Type: text/html
Content-Length: 150
<html>
<head>
<title>Request Failed</title>
</head>
<body>
<p>Task #100 is not recognized.</p>
</body>
</html>
如何修复
首先检查响应体。大多数 API 和框架会返回字段级的错误详情,说明哪个值失败以及原因。利用这些信息精确定位问题所在。
在发送之前,先将请求体与预期的 schema 进行校验。常见的触发原因包括:缺少必填字段、数据类型错误(在 API 期望数字的地方发送了字符串)、邮箱或日期格式无效、唯一值重复,以及枚举值超出允许集合。
确认 Content-Type 头与请求体格式相符。以 text/plain 内容类型发送 JSON 会导致许多服务器解析失败。
在 Laravel 中,422 通常意味着表单校验规则未通过。检查 JSON 响应中的 errors 对象,查看失败的字段名和校验消息。在 Rails 中,创建或更新时模型校验失败默认返回 422。检查 model.errors 获取详情。
对于 GitHub 或 Shopify 等 REST API,验证请求负载是否与当前 API 版本匹配。字段名、必填参数和可接受的值会随版本变化。
在服务器端,返回结构化的错误响应,列出每个无效字段、被拒绝的值以及预期格式。笼统的 “validation failed” 消息会迫使客户端去猜测原因。
代码参考
.NET
HttpStatusCode.UnprocessableEntity
Rust
http::StatusCode::UNPROCESSABLE_ENTITY
Rails
:unprocessable_entity
Go
http.StatusUnprocessableEntity
Symfony
Response::HTTP_UNPROCESSABLE_ENTITY
Python3.5+
http.HTTPStatus.UNPROCESSABLE_ENTITY
Apache HttpComponents Core
org.apache.hc.core5.http.HttpStatus.SC_UNPROCESSABLE_CONTENT
// deprecated alias: SC_UNPROCESSABLE_ENTITY
Angular
@angular/common/http/HttpStatusCode.UnprocessableEntity