全新 HTTP QUERY 方法:带有请求体的 GET 请求

全新 HTTP QUERY 方法:带有请求体的 GET 请求

历经 26 年,HTTP 终于迎来了专为复杂搜索打造的方法——它将彻底改变 API 设计的方方面面

自 1996 年以来,HTTP 一直是 Web 的脊梁。在近三十年的时间里,核心方法集——GET、POST、PUT、DELETE、PATCH——几乎没有改变。开发者在它们的基础上构建了庞大的 REST API 帝国。对于大多数使用场景,它们运行得良好。

但一直存在一个空白。一个结构性的、令人头疼的、有时甚至是危险的空白,每个 API 开发者都曾遭遇过:当你需要搜索数据,而搜索本身又很复杂时,你该怎么办?

2026 年 7 月 17 日,这个空白终于有了官方答案。QUERY HTTP 方法——于 2026 年 6 月 15 日标准化并在 RFC 9148 中正式定义——是 HTTP 方法家族在很长一段时间里的首次新增。它解决了一个 GET 和 POST 从未能干净利落处理的实际问题。

问题所在:GET 无法处理复杂搜索

GET 是数据获取的主力军。你请求一个 URL,服务器返回数据给你。简单、干净、可缓存。对于直接的查找——“给我用户 42”或“列出所有已发布的文章”——GET 是完美的。

但现代应用程序并不总是提出简单的问题。

假设你正在构建一个分析仪表板。用户希望通过 12 个不同的参数进行筛选:日期范围、嵌套的地理区域、特定产品类别、带有布尔逻辑的用户细分以及自由文本搜索查询。该筛选条件集很容易就会超过 1,000 字节。

这正是 GET 崩溃的地方。GET 请求中的所有内容都包含在 URL 中。而 URL 存在实际的长度限制。浏览器会限制它们,代理会截断它们,服务器会拒绝它们。RFC 2616 建议服务器至少处理 8,000 字节,但许多现实世界的部署在达到该限制之前就已经无法承受了。

更糟糕的是,这些 URL 参数会被记录在各个地方。浏览器历史记录会捕获完整 URL。代理服务器会缓存它。服务器访问日志会存储它。如果你的搜索包含敏感数据——患者 ID、社会安全号码片段、内部账户引用——那么这些信息现在就以明文形式散布在你无法控制的多个系统中。

这不是理论上的担忧。这是一个现实中令人头疼的合规问题。

问题所在:POST 是一种谎言

于是开发者做了开发者一直在做的事——绕过限制。“用 POST 就行了,”有人在代码审查中说。“你可以在 POST 请求中放一个 JSON 请求体,这样请求体就不会出现在 URL 里了。”

技术上确实如此。但在语义上是错误的。

POST 被设计用于修改数据。它告诉服务器:“我正在向你发送一些东西——创建一个资源,触发一个流程,修改某些状态。”这是 HTTP 规范所阐述的。这是 Web 应用程序防火墙所期望的。这也是服务器框架所假设的。

当你使用 POST 搜索数据时,你是在欺骗技术栈中的每一层。

这不仅仅是哲学上的纯粹性问题。它会带来真正的后果:

  • 缓存机制失效。 大多数 HTTP 缓存——CDN、反向代理、浏览器缓存——默认不会缓存 POST 响应,因为 POST 暗示响应每次都可能不同(因为服务器状态发生了改变)。
  • 意外的副作用。 某些服务器框架和中间件对 POST 的处理有所不同。它们可能会写入审计日志、触发 Webhook 或应用不同的速率限制规则——这一切仅仅是因为你的“搜索”端点看起来像是一个“创建”端点。
  • CSRF 风险增加。 POST 端点具有不同的跨源安全语义。使用 POST 的搜索端点现在需要 CSRF 防护,而 GET 端点则不需要。
  • 重试变得危险。 如果请求超时,客户端可以安全地重试 GET 请求(它是幂等的)。重试 POST 请求可能会创建重复记录——而你的“搜索”端点根本就不应该创建任何内容。

多年来,这种不匹配一直是 Bug、安全漏洞和架构尴尬的根源。GraphQL 尽管有其诸多优势,却使这种情况变得更加普遍——大多数 GraphQL 实现将查询作为 POST 请求发送,这意味着对 GraphQL API 的每一次读取操作都背负着写入操作的语义包袱。

迎来 QUERY:应运而生的正确工具

QUERY 方法名副其实:一个支持请求体的 GET 请求。

以下是使其与众不同的原因:

它是安全且只读的。 QUERY 方法被定义为一种安全、幂等的操作。连续发送十次相同的 QUERY 请求将返回相同的结果,对服务器产生零副作用。不会创建数据,不会更改状态,也不会意外触发审计日志。

它支持请求体。 就像 POST 一样,你可以在请求体中包含结构化数据——JSON、XML,或者你的 API 所使用的任何格式。你复杂的搜索筛选条件、嵌套对象和几 KB 大小的载荷完全无需体现在 URL 中。

它传递了明确的意图。 当服务器收到 QUERY 请求时,对于客户端的需求没有任何歧义。它就是想读取数据。仅此而已。服务器无需去猜测这个 POST 究竟是搜索还是创建操作。

它具备原生可缓存性。 与 POST 的变通方案不同,QUERY 在 HTTP 协议层运行,并具备适当的缓存语义。缓存和 CDN 可以缓存 QUERY 响应,因为该方法明确声明其不会更改服务器状态——这是 POST 永远无法保证的。

最后一点值得强调。GraphQL 能极其出色地处理复杂筛选,但它是在应用层工作的。大多数 GraphQL 查询都以 POST 请求形式传输,而服务器通常不会原生缓存 POST 响应。QUERY 方法在传输层运行,这意味着 HTTP 基础设施——代理、CDN、负载均衡器——可以在无需特殊应用级配置的情况下参与缓存。

QUERY 请求的样子

如果你曾经编写过 HTTP 请求,你会对此感到熟悉:

QUERY /api/analytics/events HTTP/1.1
Host: api.example.com
Content-Type: application/json
Accept: application/json

{
  "dateRange": {
    "start": "2026-01-01",
    "end": "2026-06-30"
  },
  "filters": {
    "regions": ["us-west-2", "eu-central-1"],
    "eventTypes": ["purchase", "refund"],
    "minAmount": 50.00
  },
  "groupBy": ["region", "month"],
  "limit": 100
}

就是这样。URL 保持干净。请求体承载了所有的复杂性。而每一个 HTTP 基础设施组件都知道这个请求是一个读取操作。

安全视角:新方法,新攻击面

这正是事情变得有趣——且有点吓人的地方。

QUERY 方法解决了 GET 和 POST 在复杂读取方面的结构性问题。但向 Web 基础设施引入一种全新的 HTTP 方法,也为攻击者和安全研究人员开辟了一个重大的新游乐场。

缓存变得棘手

QUERY 是可缓存的,且拥有请求体。这种组合对大多数 HTTP 基础设施来说是全新的。

传统的缓存使用 URL 和某些标头作为缓存键。对于 QUERY,服务器和代理必须同时将请求体包含在缓存键中。如果缓存实现弄错了这一点——例如仅以 URL 为键而忽略了请求体——不同用户的搜索结果就可能会相互泄露。

更糟糕的是,如果请求体中的敏感数据最终进入了缓存日志或调试输出中,你不过是用一种日志记录问题(访问日志中的 URL 参数)换成了另一种(缓存调试日志中的请求体)。

经典漏洞,全新矢量

每一种新的 HTTP 方法都会为现有的漏洞类型带来新的机会:

  • 输入验证失败。 你的 WAF 是否像验证 POST 请求体那样验证 QUERY 请求体?如果没有,攻击者可能会将恶意载荷走私绕过你的防御。
  • 速率限制漏洞。 如果你的速率限制器统计 GET 和 POST 请求,但对 QUERY 一无所知,攻击者就能获得免费的请求机会。
  • CSRF 与 CORS 混淆。 浏览器和框架需要正确处理 QUERY 的跨源语义。在早期采用阶段,错误配置几乎是必然会出现的。
  • HTTP 请求走私。 不理解 QUERY 的负载均衡器和反向代理可能会误解析请求,制造出走私机会,导致前端和后端在“一个请求在哪里结束、下一个请求从哪里开始”的问题上产生分歧。
  • 方法混淆。 如果 WAF 或中间件遇到了未知方法并退回到默认处理程序,它可能会应用完全错误的安全策略。

这些并不是假设的风险。它们与 HTTP/2 引入、WebSockets 问世以及其他重大协议变更进入生产基础设施时出现的 Bug 属于同一类型。其规律早已被验证:新的协议特性会在工具跟上之前创造出暂时的安全空白。

采用现状

截至 2026 年年中,采用尚处于早期阶段:

  • 浏览器 开始添加支持,但尚未普及。
  • Web 应用程序防火墙 正在更新其规则集,以识别并妥善过滤 QUERY 请求。
  • CDN 正在推出针对 QUERY 的感知请求体缓存支持,但配置各不相同。
  • API 框架 ——Express、FastAPI、Spring、ASP.NET——正在其最新版本中添加 QUERY 处理程序。
  • HTTP 客户端库 正在更新以支持发送 QUERY 请求。

全面、广泛的采用需要时间。这是协议层面的变更,这意味着技术栈的每一层——从浏览器到 CDN,再到反向代理、应用框架以及 WAF——都需要理解这个新方法。

你现在应该做什么

如果你是后端开发者或 API 设计师:

  1. 阅读 RFC。 RFC 9148 是规范性标准。在实现之前请先理解其语义。
  2. 审计你的基础设施。 检查你的反向代理、负载均衡器和 WAF 是否能正确透传 QUERY 请求。许多较旧的配置默认会阻止未知的 HTTP 方法。
  3. 不要急于上线生产环境。 从内部 API 或开发环境开始。在向公共互联网暴露 QUERY 端点之前,先让你的工具成熟起来。
  4. 更新你的缓存策略。 如果你计划缓存 QUERY 响应,请确保你的缓存键包含请求体的哈希值,而不仅仅是 URL。
  5. 测试你的安全控制。 验证速率限制、输入验证、CORS 和身份验证在配合 QUERY 时都能正确工作——不要假设它们天然支持。

如果你是安全研究人员,这是一个巨大的机会。全新的 HTTP 方法接入生产基础设施意味着到处都有全新的攻击面。现在就开始研究 QUERY 吧,因为早期采用阶段出现的 Bug 往往影响最大。

更广阔的视角

QUERY 方法并不是一场革命。它是一次纠偏。26 年来,开发者一直在将 GET 和 POST 用于这两种方法都不是为了其而设计的用途——并为此付出了安全漏洞、缓存失效和架构尴尬的代价。

QUERY 不会取代 GET。它也不会取代 POST。它填补了一个多年前就应该被填补的空白:一个支持请求体的安全、只读的 HTTP 方法。

协议已正式发布。RFC 已出版。生态系统正在适应。无论你是构建 API、加固基础设施还是寻找漏洞——QUERY 方法都是你需要去理解的内容。

Web 刚刚迎来了一个新的动词。明智地使用它。

优点

  • 解决 URL 长度限制: 复杂的搜索载荷从 URL 移至请求体——不再会被截断
  • 安全性提升: 敏感搜索参数不再泄露在浏览器历史记录、访问日志和代理缓存中
  • 正确的语义: 服务器、中间件和 WAF 无需猜测即可区分读取与写入操作
  • 原生可缓存性: HTTP 基础设施可以缓存 QUERY 响应——不像 POST 变通方案那样
  • 幂等且安全: 重试是无害的,这简化了分布式系统中的错误处理
  • 协议层解决方案: 适用于所有 REST API,无需像 GraphQL 那样进行应用层的变通

缺点

  • 新增攻击面: 为走私、方法混淆、CSRF 和 CORS 问题引入了全新的途径
  • 缓存复杂性: 缓存实现必须在键中包含请求体——配置错误会导致数据泄露
  • 采用缓慢: 在端到端可靠运行之前,浏览器、CDN、WAF 和框架全都需要更新
  • 工具缺失: 调试工具、监控仪表板和日志解析器可能尚不支持 QUERY
  • 基础设施阻碍: 较旧的反向代理和负载均衡器可能会静默丢弃或拒绝 QUERY 请求
  • 虚假的安全感: 将参数从 URL 中移出并不能消除日志记录风险 — 请求体仍可能被记录

注意事项

本文讨论了 RFC 9148 中定义的 QUERY HTTP 方法,该方法于 2026 年 6 月实现标准化。浏览器支持、框架支持和基础设施兼容性正在迅速演进。在未验证技术栈的每一层(从 CDN、WAF 到应用框架)都能正确处理这一新方法之前,切勿在生产环境中部署 QUERY 端点。此处描述的安全特性建立在正确实现的基础上;配置错误的基础设施可能会引入 QUERY 本旨在预防的安全漏洞。请务必先在受控环境中进行测试。

常见问题

  • 什么是 HTTP QUERY 方法?它与 GET 有何不同?
  • 我现在可以在生产环境 API 中使用 QUERY 吗?
  • QUERY 与通过 POST 发送搜索有效载荷相比如何?
  • CDN 和代理服务器是否会正确缓存 QUERY 响应?
  • QUERY 方法会引入哪些安全风险?
  • 对于复杂的数据获取,QUERY 会取代 GraphQL 吗?
  • 如何向我的 Express 或 FastAPI 应用程序添加 QUERY 支持?
  • 如果我的 WAF 无法识别 QUERY 方法会发生什么?

标签

#http #query-method #rfc-9148 #api-design #web-security #rest-api #caching #http-methods

Free field guide

Docker Security Checklist

Lock down your containers from build to runtime — 29 practical controls covering images, runtime flags, secrets, and the daemon. Enter your email — you'll get the PDF instantly, plus new posts on Docker, Linux & security.