jaywcjlove / quick-rss

A powerful and intuitive macOS desktop RSS reader that helps you manage and read your favorite RSS feeds with ease.

Home Page:https://wangchujiang.com/quick-rss/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

历史性时刻!全新 HTTP 方法 QUERY 提议成为 GET 和 POST 的替代方案

jaywcjlove opened this issue · comments

📋 简介

HTTP QUERY 方法旨在提供一种新的请求方式,它允许通过请求体传递复杂的查询参数,而无需将参数嵌入到URL中。与GET类似,QUERY是安全且幂等的,不会改变资源的状态;与POST类似,它支持请求体的使用。该方法特别适合大规模查询数据的情况,避免了URI长度限制。QUERY响应支持缓存,并允许服务器通过返回Location或Content-Location字段来提供查询结果或执行重复查询。

image

✨ 像 GET 一样,不修改资源状态。
📦 像 POST 一样,可以在请求中发送 body。
💾 响应可被缓存。

HTTP协议中的“QUERY”方法作为一种全新请求方式,旨在弥补GET和POST的不足,特别是在处理复杂查询时提供更多灵活性和高效性。下面将从背景、工作原理、优势、使用场景、安全性等多个方面详细介绍“QUERY”方法。

1. 背景与起源

在现有的HTTP方法中,GET和POST是最常见的请求方式。GET方法用于从服务器检索资源,它通过URL传递参数。这种方式虽然直观,但有时会遇到实际问题,比如URL长度的限制以及复杂查询参数的嵌入不便。而POST方法则允许通过请求体发送数据,常用于数据提交或执行不安全操作的场景。然而,POST操作并不被认为是安全和幂等的,并且通常会引起服务器的状态变化,因此并不适合那些需要重复执行且不改变资源状态的查询。

针对这些限制,HTTP工作组提出了“QUERY”方法,它结合了GET和POST的优点:一方面,它允许通过请求体发送复杂的查询参数,解决了URL长度限制的问题;另一方面,它确保了请求是安全和幂等的,不会对服务器资源产生副作用。

2. QUERY方法的工作原理

“QUERY”方法的核心是通过请求体传递查询数据,而非通过URL。这意味着查询参数可以更加复杂和详细,无需受限于URL的长度限制。例如,传统的GET请求可能会包含以下内容:

GET /feed?q=foo&limit=10&sort=-published HTTP/1.1
Host: example.org

然而,当查询参数变得更为复杂、甚至达到数千字节时,GET请求可能无法再承载如此大量的数据。在这种情况下,使用QUERY方法可以将查询数据放在请求体中,而不受URL长度的限制:

QUERY /feed HTTP/1.1
Host: example.org
Content-Type: application/x-www-form-urlencoded

q=foo&limit=10&sort=-published

在这个例子中,查询参数被放置在请求体中,解决了URL长度的问题。同时,QUERY方法保持了GET的安全性和幂等性,这意味着无论请求执行多少次,服务器资源的状态都不会发生变化。

3. 安全性与幂等性

“安全性”(safe)和“幂等性”(idempotent)是HTTP请求方法的重要属性。安全性意味着请求不会修改服务器上的资源,幂等性则表示同一请求多次执行的结果是相同的。

GET方法和HEAD方法都被认为是安全和幂等的,因为它们仅用于获取资源,不会对资源状态产生影响。POST方法则不具备这些属性,因为它常常用于创建、修改或删除资源。QUERY方法在这方面与GET类似:它是安全的,也具有幂等性。无论QUERY请求执行多少次,资源的状态都不会发生变化,这使得它非常适合用于只读查询场景。

此外,QUERY方法允许服务器响应时返回各种HTTP状态码。例如,当查询成功但没有返回任何数据时,服务器可以返回204 No Content;当查询结果较大时,服务器还可以通过3xx重定向指向查询结果的另一个资源。

4. 缓存与性能优化

与GET方法类似,QUERY方法的响应是可缓存的。这意味着在某些情况下,服务器返回的查询结果可以被缓存下来,用于后续的请求。缓存可以显著提高应用程序的性能,尤其是对于一些耗时较长、结果不频繁变化的查询。

具体来说,QUERY方法的缓存机制依赖于HTTP缓存规范([HTTP-CACHING]),其缓存键不仅包括请求的URI,还包括请求体的内容。因此,缓存机制可以识别具有相同查询内容的请求,并复用缓存结果。为了提高缓存效率,QUERY请求的缓存键可以通过内容归一化(normalization)来去除语义上不重要的差异。例如,服务器可以去除请求体中的编码信息或根据内容格式的规范进行归一化处理。

这种缓存机制不仅减少了服务器的负载,还可以大幅提高查询的响应速度,特别是在大规模查询或高并发访问的场景下。

5. QUERY方法的应用场景

QUERY方法的设计初衷是解决一些GET方法难以处理的问题,尤其是在需要发送大量查询数据的场景中。以下是一些典型的使用场景:

  • 复杂查询操作:当查询参数过多或包含嵌套结构时,使用QUERY可以避免URL长度限制,同时简化查询参数的组织方式。
  • 分页与过滤操作:在RESTful API设计中,分页和过滤是常见需求。通过QUERY方法,开发者可以轻松传递复杂的过滤条件,而不需要担心URI的长度。
  • 日志与分析查询:一些应用需要针对大量数据进行复杂的分析查询,QUERY方法允许将这些查询参数放在请求体中,同时确保查询操作是安全且幂等的。

6. QUERY方法的语法与请求头字段

与其他HTTP方法类似,QUERY方法允许开发者在请求中使用多种媒体类型。例如,开发者可以通过Content-Type头字段指定查询参数的格式,如application/json或application/x-www-form-urlencoded。同时,服务器也可以通过返回的Accept-Query头字段表明它支持哪些查询格式。例如:

Accept-Query: application/json, application/xml

这种机制允许客户端和服务器之间就查询格式进行协商,确保请求和响应的兼容性。

7. 安全考虑

QUERY方法在安全性方面与其他HTTP方法类似,尤其是与GET方法。在某些情况下,使用QUERY方法传递查询参数而不是通过URI,可以提高查询的隐私性,因为URI可能会被日志记录下来。而请求体中的内容则相对更为隐私,不会被URL日志记录。

不过,需要注意的是,如果服务器为QUERY请求生成了一个临时资源(例如通过Location或Content-Location头字段),应确保该资源的URI不会以明文形式暴露原始的查询内容,以避免潜在的安全风险。

8. IANA注册

根据规范,QUERY方法已经被提交到IANA(互联网号码分配机构)进行注册。未来,QUERY方法将成为HTTP协议的一部分,与GET、POST等方法共同为开发者提供更多的请求选择。

9. 总结

HTTP的QUERY方法为开发者提供了一种在不影响资源状态的前提下,执行复杂查询的新方式。它结合了GET和POST的优点,允许通过请求体传递大量查询参数,同时确保查询是安全和幂等的。通过引入缓存机制和灵活的请求体支持,QUERY方法适合于许多复杂的查询场景,并为提升应用性能提供了可能。

这一方法的提出不仅解决了当前HTTP请求方式的一些局限性,还为未来的Web应用开发提供了更多的可能性。开发者可以通过合理使用QUERY方法,优化查询操作的效率和安全性,从而构建更高效、更可靠的应用。

🔗 链接

https://www.ietf.org/archive/id/draft-ietf-httpbis-safe-method-w-body-05.html