HTTP QUERY 方法是一种新的请求方法,定义于 RFC 10008(2026 年 6 月)。它把查询放在请求体里,并且既安全又幂等。可以把它看成带请求体的 GET:你得到 POST 容纳复杂过滤器的空间,也得到 GET 在缓存和自动重试上的保证。
如果你把 3 KB 的过滤器塞进 URL,或把只读搜索发成 POST,然后看着缓存和重试逻辑忽略它,QUERY 就是针对这件事的。本指南说明规范写了什么、QUERY 与 GET 和 POST 如何比较、今天哪些工具支持它,以及如何测试一个 QUERY 端点。
什么是 HTTP QUERY 方法?
QUERY 是一种 HTTP 方法。它要求目标资源执行请求内容所描述的查询,并返回结果。请求体和它的 Content-Type 定义查询。该方法是安全的(客户端预期没有状态变化),也是幂等的(重复执行效果相同),所以客户端、代理和缓存可以像 GET 一样重试和缓存它。
规范是 RFC 10008《The HTTP QUERY Method》,2026 年 6 月发布的提议标准,作者是 Julian Reschke(greenbytes)、James M. Snell(Cloudflare)和 Mike Bishop(Akamai)。IANA 已把它加入 HTTP 方法注册表,标记为「safe: yes, idempotent: yes」,就在它差点成为的 WebDAV 时代 SEARCH 方法旁边。
一个 QUERY 请求长这样:
QUERY /contacts HTTP/1.1
Host: example.org
Content-Type: application/x-www-form-urlencoded
Accept: application/json
select=surname,givenname,email&limit=10&match=%22email=*@example.*%22
服务器以 200 OK 回答,结果在响应体里。
为什么 GET 和 POST 不够
QUERY 出现之前,复杂读取只有两条路,两条都有漏洞。
GET 把一切放进 URL。 RFC 10008 列出四个问题:
- 大小限制无法事先知道,因为请求会经过许多系统。RFC 9110 只建议发送方和接收方至少支持 8,000 个八位字节。
- 把结构化数据编码成合法 URI 很浪费。
- URI 被记录和加入书签的频率远高于请求体,对敏感过滤器是隐私问题。
- 查询输入的每一种组合都变成自己的资源。
带请求体的 GET 也不是答案。 RFC 9110 说,GET 请求里的内容没有定义语义。有的服务器会读,有的会丢掉,有的代理会拒绝。你不能指望整条路径都认它。
POST 能用,但它谎报了意图。 POST 搜索可以跑通,但没有任何东西告诉客户端、缓存、代理或重试库:这个操作是只读的。于是缓存跳过它,连接断开后客户端也不会重试。如果你不得不给一次纯读取加上幂等键,只为了让重试安全,你已经体会过这一点。幂等键可以看「幂等键」。
QUERY 保留 POST 的请求体,并加上 GET 的保证。
QUERY、GET 和 POST
下面的比较基于 RFC 10008 的表 1:
| 属性 | GET | QUERY | POST |
|---|---|---|---|
| 安全 | 是 | 是 | 可能不是 |
| 幂等 | 是 | 是 | 可能不是 |
| 请求体 | 没有定义的语义 | 预期有,用来定义查询 | 预期有 |
| 查询本身的 URI | 是,按定义 | 可选,通过 Location |
否 |
| 结果的 URI | 可选,通过 Content-Location |
可选,通过 Content-Location |
可选,通过 Content-Location |
| 可缓存 | 是 | 是,请求体是缓存键的一部分 | 仅供之后的 GET 或 HEAD |
| 浏览器的 CORS 预检 | 简单请求不需要 | 总是需要 | 简单请求不需要 |
短结论:查询能舒服地放进 URL 时用 GET,放不下时用 QUERY,只有请求会改变状态时才用 POST。经典方法可以看「HTTP 方法」和「GET 与 POST」。
RFC 10008 定义了什么
Content-Type 是必需的
服务器必须拒绝缺少 Content-Type,或 Content-Type 与请求体不一致的 QUERY。RFC 建议这些状态码:
- 400 Bad Request:没有媒体类型,或类型与内容不符。服务器不能嗅探请求体并覆盖它。
- 415 Unsupported Media Type:资源不支持这种查询格式。
- 422 Unprocessable Content:格式没问题,但查询无法执行,例如 SQL 点了一个不存在的表。
- 406 Not Acceptable:客户端要求的响应类型是资源无法产生的。
Location 和 Content-Location
服务器可以返回两个可选响应头,让一次 QUERY 以后能用 GET 取到:
Content-Location指向这次具体运行所保存的结果。它可能是临时的。Location指向保存的查询本身。对它发 GET 会用新数据重跑查询,不必再发送请求体。
RFC 建议客户端对重复请求改用 Location URI 上的 GET,因为 GET 缓存更简单。如果查询含敏感数据,而你返回了其中任一响应头,URI 不应包含原始请求体里的敏感部分。
缓存
QUERY 响应可以缓存。缓存键必须包含请求内容和相关元数据,例如媒体类型。缓存可以先规范化请求体,例如去掉内容编码,或对 +json 类型规范化 JSON,以提高命中。规范警告,糟糕的规范化会返回错误响应,所以预期 CDN 在这里会很谨慎。
重定向
301、302、307 或 308 表示「把同一个 QUERY 发到新 URI」。与 POST 不同,QUERY 在 301 或 302 上不得被改写成 GET。303 See Other 表示「用 GET 到这个 URI 取结果」。
Accept-Query 响应头
Accept-Query 是新的响应头,用来宣告 QUERY 支持,以及资源接受的查询格式。它是结构化字段列表,要按列表解析:
Accept-Query: "application/jsonpath", application/sql;charset="UTF-8"
客户端也可以用 OPTIONS 发现支持并读取 Allow 头,或直接发送 QUERY,再处理 405 Method Not Allowed。
今天哪些工具支持 QUERY?
支持并不均衡,所以要测试你自己的技术栈。以下是 2026 年 10 月 28 日确认的结果:
| 工具 | 结果 |
|---|---|
Node.js 24 http 服务器 |
http.METHODS 包含 QUERY;普通服务器收到了方法和请求体 |
Node.js 24 fetch |
发送了带 JSON 请求体的 QUERY |
| curl 8.7 | curl -X QUERY 配合 -d 发送了方法和请求体 |
Python 3.14 http.client |
发送了带请求体的 QUERY |
| OpenAPI 3.2 | Path Item Object 有 query 字段,用于 QUERY 操作 |
| 来源产品 CLI 2.2.12 | 原文称 endpoint-create schema 接受 "method": "query"。Apifox 是否具备该能力,待核实 |
下面是对本地 Node 服务器使用的 curl:
curl -i -X QUERY http://localhost:3000/products \
-H "Content-Type: application/json" \
-d '{"q":"running shoe","limit":2}'
Fetch 标准只禁止 GET 和 HEAD 带请求体,所以浏览器可以发送带请求体的 QUERY。但 QUERY 不是 CORS 安全列表方法,因此每个跨源 QUERY 都会触发预检。服务器必须在 Access-Control-Allow-Methods 里列出 QUERY。
缺口在网络中段:反向代理、API 网关、WAF 和 CDN 会用方法白名单,或缓存键不包含请求体。上线前检查每一跳。APIs You Won't Hate 通讯 指出,许多 Web 框架已经直接处理 QUERY,或通过自定义方法路由处理。
如何采用 QUERY 而不弄坏客户端
你不必拆掉现有的 POST 搜索端点。
- 在 POST 路由旁边加上 QUERY。 两者指向同一个处理函数。新客户端用 QUERY,旧客户端继续工作。
- 宣告它。 在资源上返回
Accept-Query,并在OPTIONS和405响应的Allow里包含QUERY。 - 强制 Content-Type。 按 RFC 的建议返回 400 或 415,对能解析但无法执行的查询返回 422。
- 在 405 或 501 时回退。 某一跳拒绝 QUERY 时,客户端应用同一请求体改发 POST。
- 修好 CORS。 为浏览器客户端把
QUERY加进Access-Control-Allow-Methods。 - 决定缓存。 只在缓存会把请求体放进缓存键时,才开启共享缓存。否则返回
LocationURI,让客户端对它发 GET。 - 写进文档。 在 OpenAPI 3.2 里,把操作定义在路径项的
query:下:
openapi: 3.2.0
paths:
/products:
query:
summary: Search products
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/ProductQuery'
responses:
'200':
description: Matching products
短而简单的过滤器可以继续作为 GET 上的查询字符串。查询字符串可以看「查询字符串」。RFC 10008 自己也说,如果查询短到那种程度,GET 多半是更好的选择。
让编码智能体测试 QUERY 端点
新方法意味着要检查成功路径、每一种错误码,以及回退路由。可以交给 Claude Code、Codex 或 Cursor,用上面的 curl 或你现有的接口测试工具来跑。
值得覆盖的断言:合法 JSON 请求体返回 200 且结果为数组;Content-Type: text/plain 返回 415;没有 Content-Type 返回 400。
原文给出了来源产品 CLI 的安装、创建端点和运行测试的命令,并提到其免费方案最多 4 名用户。Apifox 是否提供同名 CLI,以及是否接受 "method": "query",待核实,因此不照搬。
常见问题
HTTP QUERY 方法是正式标准吗? 是。RFC 10008 是 2026 年 6 月发布的标准轨道提议标准 RFC。IANA 在 HTTP 方法注册表里把 QUERY 列为安全和幂等。
QUERY 只是带请求体的 GET 吗? 接近,但定义得更好。RFC 9110 没有给 GET 请求体定义语义,中间盒可以忽略或拒绝它。QUERY 把请求体定为查询,要求有 Content-Type,并把请求体放进缓存键。
什么时候用 QUERY 而不是 POST? 任何只读搜索或过滤器,只要对 URL 来说太大或太敏感,就用 QUERY。会创建或改变内容的请求仍用 POST。
浏览器能发送 QUERY 请求吗? 能,通过 fetch 的自定义方法。跨源 QUERY 请求总是需要 CORS 预检,所以服务器必须允许该方法。
QUERY 响应会被缓存吗? 可以。缓存必须把请求体及其元数据放进缓存键。许多 CDN 和代理还没这样做,所以要检查你的,或返回客户端可以 GET 的 Location URI。
OpenAPI 支持 QUERY 吗? OpenAPI 3.2 在 Path Item Object 上增加了 query 字段,用于 QUERY 操作,因此不必用扩展就能写进文档。
开发必备:API 全流程管理神器 Apifox
介绍完上文的内容,我想额外介绍一个对开发者同样重要的效率工具 —— Apifox。作为一个集 API 文档、调试、设计、测试、Mock、自动化测试于一体的工具,Apifox 是目前提升研发效率的首选。
如果你正在开发项目,不妨试试其极其友好的界面设计,它完全兼容 Postman 和 Swagger 数据格式,导入数据非常方便,,即使是新手也能很快上手,点击这里即可注册使用。

值得一提的是,除了个人和常规团队使用,针对有高安全合规要求、或需要在内网环境协作的企业,Apifox 还提供了深度定制的私有化部署方案。
获取专属报价与部署方案
详细的私有化部署系统架构与安全白皮书
针对您公司规模的专属报价单
免费的 1v1 专属产品演示 (Demo) 机会