HTTPQUERY
English

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