为啥说“HTTP 是无状态协议”?

Posted

技术标签:

【中文标题】为啥说“HTTP 是无状态协议”?【英文标题】:Why is it said that "HTTP is a stateless protocol"?为什么说“HTTP 是无状态协议”? 【发布时间】:2012-10-23 09:39:43 【问题描述】:

HTTP 有 HTTP Cookie。 Cookies允许服务器跟踪用户状态、连接数、上次连接等。

HTTP 具有持久连接 (Keep-Alive),可以从同一个 TCP 连接发送多个请求。

【问题讨论】:

另一个我看不到“无状态”的领域是授权——尤其是代理授权。在协商过程中似乎是有状态的。对于 NTLM 身份验证,客户端需要记住代理身份验证的类型,并且服务器需要有状态,因为 NTLM 消息类型有一个序列。所以我不确定我是否理解答案。 我现在应该添加 HTTP/1.1 吗?因为我认为 HTTP/2 有状态。 HTTP/2 是有状态的。 HTTP 1 是无状态的。 用于 HTTP 1 的后续添加(如 cookie)添加了状态。这些添加不属于“核心”HTTP 1 规范。这就是为什么说 HTTP 1 是无状态协议的原因,尽管实际上它不是。另一方面,HTTP/2 在设计时内置了有状态组件。无需添加即可满足被标记为“有状态”的要求。 其他相关:***.com/questions/11067500/…***.com/questions/36178447/… 【参考方案1】:

即使多个请求可以通过同一个 HTTP 连接发送,服务器也不会对它们通过同一个套接字到达的附加任何特殊含义。这只是一个性能问题,旨在最大限度地减少为每个请求重新建立连接所花费的时间/带宽。

就 HTTP 而言,它们仍然是独立的请求,并且必须包含足够的信息来完成请求。这就是“无国籍”的本质。如果缺少服务器知道的一些共享信息(在大多数情况下是 cookie 中的会话 ID),请求将不会相互关联。

【讨论】:

当服务器记住一个会话(服务器端)并根据它定制用户体验时会发生什么? @NurShomik:请参阅 ***.com/a/3521393/319403 了解会话通常如何工作的说明。 @Andrew:HTTP 不是“建立在”TCP 之上的,TCP 的状态也不是 HTTP。两者是堆栈中不同层的完全独立的协议。如果你愿意,你可以通过命名管道提供 HTTP,或者甚至通过发送文件,如果你有足够的受虐狂同意这样做,它会工作,因为 HTTP 与传输协议无关。在那个层面上,一切都只是请求和响应。这使得 HTTP 本身是无状态的,无论低级或高级协议可能使用/维护/要求什么状态。 @cHao 好吧,我承认。 如果我们将无状态定义为“不是必要需要有状态才能运行”(参见dimo414的回答,下面列出了来自***的HTTP中的状态选项),并且如果我们严格地看待每个协议本身而不是基于它下面的层,那么是的,我可以同意 HTTP 是“无状态的”。【参考方案2】:

来自Wikipedia:

HTTP 是一种无状态协议。无状态协议不需要 服务器为每个用户保留信息或状态 多个请求的持续时间。

但某些网络应用程序可能必须跟踪用户的进度 页面到页面,例如当需要 Web 服务器进行自定义时 用户的网页内容。这些情况的解决方案 包括:

HTTP cookie 的使用。 服务器端会话, 隐藏变量(当当前页面包含表单时),以及 使用 URI 编码参数进行 URL 重写,例如 /index.php?session_id=some_unique_session_code。

使协议无状态的原因是服务器不需要跟踪多个请求的状态,而不是如果它愿意就不能这样做。这简化了客户端和服务器之间的合同,并且在许多情况下(例如通过 CDN 提供静态数据)最大限度地减少了需要传输的数据量。如果需要服务器来维护客户端访问的状态,那么发出和响应请求的结构会更加复杂。事实上,模型的简单性是其最大的特点之一。

【讨论】:

似乎他们不应该正式宣布它为无状态协议,而是使用一些词来说明它可以灵活地在无状态与有状态之间切换。【参考方案3】:

因为无状态协议不要求服务器在多次请求期间保留有关每个通信伙伴的会话信息或状态。

HTTP是一种无状态协议,这意味着一旦事务结束,浏览器和服务器之间的连接就会丢失。

【讨论】:

但是,HTTP 可以使用 cookie 将信息保存在服务器中。带有 keep-alive 的 HTTP 不会关闭每个请求的连接。 查看这篇文章:- ecst.csuchico.edu/~amk/foo/advjava/notes/servlets/Cookies.html 在服务器上保存信息并不意味着连接一直处于活动状态。 @srijan 好吧,不。所以?没有人声称不这样做。【参考方案4】:

HTTP 被称为stateless protocol,因为每个请求都是独立执行的,不知道之前执行的请求,这意味着一旦事务结束浏览器与服务器也丢失了。

使stateless 协议的原因在于,在其最初的设计中,HTTP 是一个相对简单的file transfer protocol

    请求以 URL 命名的文件, 获取文件作为响应, 断开连接。

即使来自同一个客户端,一个连接与另一个连接也没有关系。这简化了客户端和服务器之间的合同,并且在许多情况下最大限度地减少了需要传输的数据量。

【讨论】:

这是不正确的,尤其是 HTTP/2,其中请求依赖于其他请求。 Cookie、HTTPS、HTTP 身份验证、Web 存储、HTTP 缓存、HTTP 流标识符、HTTP/2 标头块、HTTP/2 帧、标头压缩和机会加密都是有状态的。【参考方案5】:

现代 HTTP 是有状态的。过去的 HTTP 是无状态的。

在 Netscape 在 1994 年发明 cookie 和 HTTPS 之前,HTTP 可以被认为是无状态的。随着时间的推移,出于各种原因(包括性能和安全性)添加了许多有状态组件。但是有状态的添加就是这样,添加,所以仍然通俗地说 HTTP 是无状态的,因为核心明确寻求无状态。

虽然 HTTP 1 最初寻求的是无状态的,但许多 HTTP/2 组件正是有状态的定义。 HTTP/2 放弃了无状态目标。有状态组件不再是“添加”,而是在 HTTP/2 标准的核心中定义了有状态组件。

以下是有状态 HTTP/1 和 HTTP/2 组件的有限列表,并非详尽无遗:

Cookie,被 RFC 命名为“HTTP 状态管理机制”。 HTTPS,用于存储密钥的状态。 HTTP 身份验证需要状态。 网络存储。 HTTP 缓存是有状态的。 流标识符的真正用途是状态。它甚至以 RFC 部分的名称“流状态”。 建立流标识符的标头块是有状态的。 引用流标识符的帧是有状态的。 HTTP RFC 明确表示有状态的标头压缩是有状态的。 机会加密是有状态的。

HTTP/2 RFC 的第 5.1 节是 HTTP/2 标准定义的状态机制的一个很好的例子。

Web 应用程序将 HTTP/2 视为无状态协议是否安全?

HTTP/2 是一种有状态协议,但这并不意味着您的 HTTP/2 应用程序不能是无状态的。您可以选择不对无状态 HTTP/2 应用程序使用有状态功能。

有状态机制是后来 HTTP 对原始无状态标准的补充。 HTTP 1 被认为是无状态的,尽管在实践中我们使用标准化的有状态机制,如 cookie、TLS 和缓存。与 HTTP/1 不同,HTTP/2 从一开始就在其标准中定义了有状态组件。特定的 HTTP/2 应用程序可以使用 HTTP/2 功能的子集来保持无状态,但协议本身预计状态是常态,而不是例外。

如果尝试无状态使用它们,需要状态的现有 HTTP/1 和 HTTP/2 应用程序将会中断。例如,如果禁用 cookie,则可能无法登录某些 HTTP/1.1 网站,从而破坏应用程序。假设特定的 HTTP/1 或 HTTP/2 应用程序是无状态的可能并不安全。

错误的“HTTP 是无状态的”旧信条,与当前的 HTTP 有状态现实相去甚远。

【讨论】:

“HTTPS,存储密钥的状态”。嗯,no 与 HTTP 无关。 HTTPS = 基于 TLS 的 HTTP。关键的“存储”发生在另一个协议层中。 en.wikipedia.org/wiki/HTTPS#Difference_from_HTTP 这是一个合理的答案。但是为什么没有人支持呢? 如果 HTTP 是有状态协议,客户端负载平衡如何工作?客户端随机向任何终端服务器发送请求,一切正常。【参考方案6】:

如果协议 HTTP 被指定为状态完整协议,浏览器窗口使用单个连接与 Web 服务器进行通信,以便向 Web 应用程序发出多个请求。这使浏览器窗口有机会长时间参与浏览器窗口和 Web 服务器之间的连接并使其长时间处于空闲状态。即使客户端中的大多数连接都处于空闲状态,这也可能会造成Web服务器达到最大连接数的情况。

【讨论】:

HTTP已经有了keep-alive,这意味着服务器不会关闭连接,客户端可以在同一个连接上发出多个请求。【参考方案7】:

HTTP 是无连接的,这是 HTTP 是无状态协议的直接结果。服务器和客户端仅在当前请求期间才知道彼此。之后,两个人都忘记了对方。由于协议的这种性质,无论是客户端还是浏览器都不能保留跨网页的不同请求之间的信息。

【讨论】:

【参考方案8】:

HTTP 是无状态的。 TCP 是有状态的。 没有所谓的HTTP connection,只有HTTP requestHTTP response。我们不需要维护任何东西来制作另一个HTTP request“keep-alive” 的连接标头意味着TCP 将被后续的HTTP 请求和响应重用,而不是一直断开并重新建立TCP 连接。

【讨论】:

HTTP/2 是有状态的,并且确实有一个 HTTP 连接,称为流。 tools.ietf.org/html/rfc7540#section-5.1【参考方案9】:

什么是无状态?

一旦发出请求并将响应返回给客户端,连接将被断开或终止。服务器将忘记请求者的所有信息。

为什么是无国籍的?

网络选择使用无状态协议。这是一个天才的选择,因为网络的最初目标是允许将文档(网页)提供给非常大的数量。使用非常基本的服务器硬件的人。

维护一个长时间运行的连接会非常耗费资源。

如果网络被选择为有状态协议,那么服务器上的负载将会增加以维持访问者的连接。

【讨论】:

【参考方案10】:

我认为有人为 STATELESS 概念选择了非常不幸的名称,这就是造成整个误解的原因。它不是关于存储任何类型的资源,而是关于客户端和服务器之间的关系。

客户:我把所有的资源都放在我这边,并把所有需要处理的重要项目的“清单”发给你。做好你的工作。

服务器:好的.. 让我负责过滤重要的内容,以便为您提供正确的响应。

这意味着服务器是客户端的“奴隶”,每次请求后都必须忘记他的“主人”。实际上,STATELESS 仅指服务器的状态。

https://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm#sec_5_1_3

【讨论】:

以上是关于为啥说“HTTP 是无状态协议”?的主要内容,如果未能解决你的问题,请参考以下文章

JavaWeb-Cookie和Session

HTTP协议及常见状态码

关于Cookie

Session 和 Cookie

面试题:给我说一下你项目中的单点登录是如何实现的?

http协议