HTTP QUERY 方法说明:RFC 10008,以及它和 GET、POST 的差别

RFC 10008 定义的 HTTP QUERY 把查询放在请求体里,并且安全、幂等。本文比较 QUERY、GET 和 POST,并说明 Content-Type、缓存和现有工具支持情况。

用 Apifox,节省研发团队的每一分钟

HTTP QUERY 方法说明:RFC 10008,以及它和 GET、POST 的差别

免费使用 Apifox

相关推荐

最新文章

API

一体化协作平台

API 设计

API 文档

API 调试

自动化测试

API Mock

API Hub

立即体验 Apifox
目录

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 列出四个问题:

  1. 大小限制无法事先知道,因为请求会经过许多系统。RFC 9110 只建议发送方和接收方至少支持 8,000 个八位字节。
  2. 把结构化数据编码成合法 URI 很浪费。
  3. URI 被记录和加入书签的频率远高于请求体,对敏感过滤器是隐私问题。
  4. 查询输入的每一种组合都变成自己的资源。

带请求体的 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 搜索端点。

  1. 在 POST 路由旁边加上 QUERY。 两者指向同一个处理函数。新客户端用 QUERY,旧客户端继续工作。
  2. 宣告它。 在资源上返回 Accept-Query,并在 OPTIONS 和 405 响应的 Allow 里包含 QUERY。
  3. 强制 Content-Type。 按 RFC 的建议返回 400 或 415,对能解析但无法执行的查询返回 422。
  4. 在 405 或 501 时回退。 某一跳拒绝 QUERY 时,客户端应用同一请求体改发 POST。
  5. 修好 CORS。 为浏览器客户端把 QUERY 加进 Access-Control-Allow-Methods。
  6. 决定缓存。 只在缓存会把请求体放进缓存键时,才开启共享缓存。否则返回 Location URI,让客户端对它发 GET。
  7. 写进文档。 在 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

值得一提的是,除了个人和常规团队使用,针对有高安全合规要求、或需要在内网环境协作的企业,Apifox 还提供了深度定制的私有化部署方案。

获取专属报价与部署方案

icon 详细的私有化部署系统架构与安全白皮书
icon 针对您公司规模的专属报价单
icon 免费的 1v1 专属产品演示 (Demo) 机会
获取部署方案
* 提交后,我们的客户经理将在 1 个工作日内与您联系
林俊锋 企业微信
@Apifox 专属顾问
扫码备注: 私有化 + 公司名