新HTTP QUERY方法详解

Hacker News Top 新闻

摘要

文章解释了RFC 10008中定义的新HTTP QUERY方法,该方法通过提供一种标准、安全且幂等的带请求体方法,解决了GET和POST在复杂查询方面的限制。

暂无内容
查看原文
查看缓存全文

缓存时间: 2026/06/23 07:41

# 新 HTTP QUERY 方法详解 来源:https://kreya.app/blog/new-http-query-method-explained/ 在 RESTful API 的世界里,我们长期遵循着一套严格(且自我施加)的规则。无论是用 GET 获取数据、用 POST 创建实体,还是用 PUT 更新资源,HTTP 方法都在告诉服务器你的意图是什么。 最近,RFC 10008(https://www.rfc-editor.org/info/rfc10008/)发布了,它定义了新的 HTTP QUERY 方法。既然我们已经有了其他 HTTP 方法,为什么还需要它呢?让我们一探究竟。 从纯粹的技术角度来说,HTTP 方法只是一个字符串。理论上,与其发送 不如发送 也是可行的。但在实践中,围绕 GET、POST 等常见 HTTP 方法,存在大量 RFC 规范以及隐式、未文档化的行为。 例如,当你在浏览器中输入地址或点击书签时,浏览器会发送 GET 请求。标准 HTTP 表单只允许 GET 和 POST 作为方法。大多数代理、防火墙和 Web 服务器也只允许“标准”HTTP 方法。 那么,既然我们已经有一套运行了几十年的现有方法,为什么还要引入新的 HTTP 方法呢? ## 使用 GET 进行查询(https://kreya.app/blog/new-http-query-method-explained/#queries-using-get) 传统上,如果要筛选资源,你会在 GET 请求中使用查询参数(例如:`/api/v1/users?role=admin&status=active&sort=desc`)。这种方式在简单筛选场景下效果不错。然而,当你需要进行复杂的关系查询、深层嵌套或高级逻辑时,URL 会变得庞大、难以阅读,有时甚至会触及浏览器或服务器的字符长度限制。 其他潜在问题包括: - 发送非 ASCII 或特殊字符作为参数需要编码,这会增加请求大小。 - 服务器和其他中间件很可能会记录请求参数,在某些情况下这可能会带来问题。 - 表达某些数据结构(如数组)的方式未妥善定义,且实现各异(例如 `?roles[0]=admin&roles[1]=reporter` 与 `?roles=admin&roles=reporter` 与 `?roles[]=admin&roles[]=reporter` 的区别)。 - 同样,表达深层嵌套结构也存在类似问题。 既然这些缺点都是由于将数据作为查询参数发送引起的,那么为什么不直接发送带 JSON 请求体的 GET 请求呢?从理论上看,这应该可行。没有任何 HTTP RFC 明确禁止在 HTTP GET 请求中使用请求体,但 RFC 暗示不应这样做。结果,各种客户端、代理和 Web 服务器对带体的 GET 请求处理方式各不相同。有些直接拒绝,有些简单地丢弃请求体,而另一些则尝试解析它。 因此,使用带请求体的 HTTP GET 请求是个坏主意,因为例如在企业防火墙后面或使用不同浏览器的用户可能无法访问你的网站。这也是为什么没有新的 RFC 规定 GET 请求现在应该支持请求体,因为这会破坏大量现有实现。 ## 变通方案:使用 POST 进行查询(https://kreya.app/blog/new-http-query-method-explained/#the-workaround-querying-using-post) 由于使用 GET 发送请求体可能引入问题,变通方案是使用 POST。 虽然 POST 允许使用请求体,但它带来了显著的语义问题。POST 被定义为非幂等的,且用于资源创建或处理。 虽然这听起来可能不是大问题,但在实现失败自动重试等场景时会很麻烦。因为 GET 方法被定义为安全和幂等的,只要服务器实现正确,我们就可以在失败时重试请求,而无需担心副作用。此外,这还使得代理或其他中间件无法自动理解该操作是只读的。例如,中间件可能会自动缓存 GET 请求一段时间,但这对 POST 请求不起作用。 ## QUERY 方法(https://kreya.app/blog/new-http-query-method-explained/#the-query-method) 上述所有原因促成了 QUERY 方法的规范,经过多年的讨论后终于发布。QUERY 方法并无特殊之处,RFC 大致说明它与 GET 方法类似,但带有一个请求体。它被设计为安全且幂等的。 QUERY 请求可以被缓存,但实现时必须小心地将请求内容纳入缓存键。总而言之,它终于为复杂搜索查询提供了合适的 HTTP 方法。 Kreya 发送 QUERY 请求的截图 ## QUERY 的注意事项(https://kreya.app/blog/new-http-query-method-explained/#query-gotchas) 人们可能会急于将所有搜索相关端点切换为使用 QUERY。在此之前,你需要考虑以下几点: - 对 HTTP QUERY 的支持仍然非常有限,并且可能会持续一段时间。它可能需要数年才能在所有地方得到完全支持。例如,Kreya(https://kreya.app/)在最近的 1.20 版本中添加了对 HTTP QUERY 的开箱即用支持(尽管之前已经可以发送自定义 HTTP 方法)。其他客户端、代理和 Web 服务器可能仍会拒绝它。 - 标准的 GET 查询(数据在 URL 参数中)仍然完全可以接受。如果没有立即需要将那些改为 QUERY 方法,就保持原样。 - 如果你的用户应该能够分享或收藏筛选数据的链接,请继续使用 GET 请求。分享 QUERY 请求的链接是行不通的。 - 为 QUERY 请求实现自定义缓存比 GET 请求更难,因为你需要考虑请求体。 ## 结论(https://kreya.app/blog/new-http-query-method-explained/#conclusion) 简而言之,HTTP QUERY 替代了只读请求中的 POST。它可能需要一段时间才能在所有地方得到完全支持,但你应该考虑(并测试!)——如果标准的 GET 请求不能满足你的用例,那么就试试它。

相似文章

RFC 10008: HTTP QUERY 方法

Lobsters Hottest

RFC 10008 定义了新的 HTTP QUERY 方法,允许包含请求体的安全、幂等且可缓存的请求,解决了 GET 和 POST 在 RPC 风格 API 中的局限性。

RFC 10008: HTTP QUERY 方法

Lobsters Hottest

RFC 10008 定义了 HTTP QUERY 方法,这是一种安全且幂等的请求方法,允许在请求体中发送查询负载,弥合了 GET 和 POST 在查询操作之间的差距。

HTTP QUERY 方法

Lobsters Hottest

本互联网草案定义了 HTTP QUERY 方法,这是一种安全且幂等的方法,允许请求处理封装的内容并返回结果,类似于 POST 但不会带来部分状态变更的风险。

现代HTTP请求

Lobsters Hottest

本文解释了现代Chrome浏览器发送的各种HTTP头部,包括sec-ch-ua、sec-fetch以及与隐私相关的头部,并提供了历史背景。