HTTP 新增 QUERY 方法:有人叫好,也有人质疑“这不就是 GET?”
2026 年 6 月,HTTP 迎来了 16 年来最重要的新增功能:IETF 发布了 RFC 10008,为 Web 引入了一种名为 QUERY 的新方法。这是自 PATCH 于 2010 年落地以来,第一个新的标准 HTTP 动词。它由 Julian Reschke、James Snell 和 Mike Bishop 编写,起源于 Asbjørn Ulsberg 在 2019 年 HTTP Workshop 上重新发起的一场讨论。
QUERY 旨在解决开发者多年来一直争论的问题。GET 是安全且幂等的,但其过滤条件必须放在 URL 中,不仅会受到长度限制、泄露到访问日志中,也难以表达嵌套结构。POST 可以携带内容丰富的正文,但它既不安全也不幂等,因此缓存会跳过它,客户端无法安全地重试它,中间系统也必须假定它会改变状态。QUERY 补上了缺失的第三种选择:像 POST 一样携带正文,同时保留读取操作所具有的安全、幂等和可缓存语义。
在实践中,过去必须压缩到 URL 中的搜索:
GET /orders?select=email&limit=10&match="email=*@example.*"复制代码现在可以改为在正文中发送过滤条件,不必担心大小问题:
QUERY /orders HTTP/1.1
Host: api.example.org
Content-Type: application/json
{ "select": ["email"], "limit": 10, "match": "email=*@example.*" }复制代码只要缓存键包含请求内容,响应就仍然可以缓存,服务器还可以通过新的 Accept-Query 字段声明支持该方法。
一个 r/webdev 讨论帖获得了超过 800 个赞,其中一位开发者问道:
为什么不允许 GET 请求携带可选正文?
另一位开发者解释了原因:
通过引入一种新方法,你可以确保对方支持请求正文。
调试请求无法正常工作的原因会容易得多。因为不支持该方法的服务器会提示“QUERY 不受支持”。
对 GET 正文进行静默失败处理是最显而易见的做法。祝你好运,希望你能调试出链路中的哪台服务器丢弃了你的正文……
在 Hacker News 上,围绕使用 GET 和可选正文也出现了类似的讨论,一位评论者总结道:
“QUERY 就是 GET”
“使用带正文的 GET 是可行的”
大家似乎都没有理解这一点。你本来就不应该使用带正文的 GET,这是一种变通手段,因此提供一种明确的方法是合理的。
能用并不意味着用法正确。
同一讨论还指出,如今就连 Cloudflare 也会伪造一个 GET 缓存键来缓存 POST:
……他们对 POST 请求缓存的非官方支持方式,是创建一个虚假的 GET 请求作为缓存键,并用它来缓存响应。正因为没有 QUERY 这样的方法,所有人才不得不采用这类变通手段。
GraphQL 和 Elasticsearch 已经通过 POST 正文传输复杂的读取请求,而 QUERY 提供了一种基于标准的替代方案,同时让这些读取请求保持可缓存性。工具生态也在逐步跟进:Rust 的 http crate 已经合并相关支持,.NET、Axum、Quarkus 和 Bruno 也在跟踪相关工作。
该规范建议将 QUERY 视为一项补充,而不是全面替代现有方法。IETF 草案历史记录了它从早期带正文的安全方法工作发展到如今标准正式发布的漫长历程。这也提醒人们,与此前的 PATCH 一样,QUERY 的实际普及很可能需要以年为单位衡量。
HTTP 是 Web 运行所依赖的请求和响应协议,其规范由 IETF 的 HTTP 工作组(即 httpbis)制定,再由 RFC Editor 以 RFC 的形式发布。新方法十分罕见,因为每种方法都必须得到客户端、服务器、代理和缓存的理解,才能在实践中可靠使用。正因如此,RFC 10008 将 QUERY 定位为 GET 和 POST 之外的可选补充,而不是对二者中任何一个的替代。