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 获取相同结果。

HTTP 请求-响应流程

三种方法对比

属性GETQUERYPOST
安全(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