HTTP新增QUERY方法:带请求体的安全查询
HTTP 新增 QUERY 方法:带请求体的安全查询
IETF HTTP 工作组定义了一个新的 HTTP 请求方法 QUERY,已于 2025 年 11 月正式编号为 RFC 10008(Proposed Standard)。它允许像 POST 一样把查询条件放在请求体里,同时保留 GET 的安全(safe)和幂等(idempotent)语义,支持缓存和自动重试。
解决什么问题
写过搜索接口的人大多遇到过这个困境:查询条件太多,URL 查询字符串放不下。
浏览器对 URL 长度有限制(Chrome 约 2MB,但实际生产环境中的 CDN、网关、代理往往更严格,常见上限 8KB 到 32KB)。复杂的搜索请求可能包含几十个过滤条件、嵌套的 JSON 结构、长 ID 列表,全塞进 ?q=foo&filters=... 的 query string 里,脆弱且不可维护。
过去的 workaround 通常有两种。一是压缩 URL,做各种编码和截断,丑且容易出错。二是改用 POST,把查询条件放进请求体。POST 没有长度限制,但 POST 在 HTTP 语义中既不安全也不幂等,意味着响应无法被标准缓存机制处理,请求失败后不能自动重试,中间件也无法将其识别为只读操作。
QUERY 方法就是来解决这个矛盾的。
QUERY 的设计
QUERY 的请求体承载查询内容,请求体格式由 Content-Type 声明。RFC 给了一个示例:
QUERY /feed HTTP/1.1 Host: example.org Content-Type: application/x-www-form-urlencoded q=foo&limit=10&sort=-published
查询条件放在请求体里,但整个请求在语义上属于安全(safe)和幂等(idempotent)。安全意味着请求不会改变服务器状态,幂等意味着重复执行结果相同。这两个属性让 QUERY 响应可以被标准缓存机制处理,请求失败后可以自动重试。
服务器还可以通过 Location 响应头为查询本身分配一个 URI,客户端后续可以用 GET 直接访问该 URI 获取相同结果。

三种方法对比
| 属性 | GET | QUERY | POST |
|---|---|---|---|
| 安全(safe) | 是 | 是 | 否 |
| 幂等(idempotent) | 是 | 是 | 否 |
| 请求体 | 无定义语义 | 有,承载查询 | 有,承载任意数据 |
| 可缓存 | 是 | 是 | 仅限未来 GET/HEAD |
| URI 标识查询本身 | 是(定义如此) | 可选(Location 头) | 否 |
QUERY 卡在 GET 和 POST 之间的空档:既有请求体解决长度问题,又保留安全和幂等语义解决缓存和重试问题。
Accept-Query 响应头
RFC 同时定义了 Accept-Query 响应头,让服务器声明支持哪些查询格式。客户端发送 OPTIONS 请求或观察响应头,就能知道目标资源接受什么格式的查询内容。
HTTP/1.1 200 OK Accept-Query: application/x-www-form-urlencoded, application/json
这让 QUERY 的协商机制更加完整,客户端不必猜测服务器期望什么格式的查询体。
适用场景
QUERY 最直接受益的场景包括:
- 复杂搜索 API:多维度过滤、排序、分页条件组合,URL query string 承载不下
- GraphQL 风格的查询:查询语句本身就是结构化数据,放在请求体里更自然
- 数据库查询代理:通过 HTTP 封装 SQL-like 查询条件
- 大量 ID 列表的批量查询:
ids=[1,2,3,...,10000]这类请求
标准化状态
QUERY 方法已经走完 IETF 标准化流程。IESG 于 2025 年 11 月 20 日批准 draft-ietf-httpbis-safe-method-w-body-14 为 RFC 10008(Proposed Standard)。HTTP 方法注册表和 HTTP 字段注册表已加入相应条目。
框架和运行时的跟进是下一步。各大 Web 框架(Spring、Express、FastAPI 等)何时原生支持 QUERY 方法,浏览器和 CDN 何时正确处理 QUERY 请求的缓存,将决定这个方法的实际采用速度。
来源:RFC 10008 (IETF) · IETF HTTP Working Group