🍓HTTP概述
HTTP是一个协议(协议是定义数据是如何内或计算机之间交换规则的系统。
设备之间的通信要求设备就正在交换的数据格式达成一致。定义格式的一组规则称为协议),其允许资源,诸如HTML文档的抓取。它是Web 上任何数据交换的基础,它是一种客户端-服务器协议,这意味着请求由接收方(通常是 Web 浏览器)发起。
从获取的不同子文档(例如文本、布局描述、图像、视频、脚本等)重建完整的文档。
客户端和服务器通过交换单独的消息(而不是数据流)进行通信。客户端(通常是 Web 浏览器)发送的消息称为请求,服务器发送的作为应答的消息称为响应。
HTTP 设计于 1990 年代初,是一种随着时间的推移而发展的可扩展协议。它是通过TCP或通过TLS加密的 TCP 连接发送的应用层协议,尽管理论上可以使用任何可靠的传输协议。由于其可扩展性,它不仅用于获取超文本文档,还用于获取图像和视频,或者将内容发布到服务器,例如 HTML 表单结果。HTTP 还可用于获取部分文档以按需更新网页。
🏳️🌈基于 HTTP 的系统的组件
HTTP 是一种客户端-服务器协议:请求由一个实体发送,即用户代理(或代表它的代理)。大多数情况下,用户代理是一个 Web 浏览器,但它可以是任何东西,例如爬行 Web 以填充和维护搜索引擎索引的机器人。
每个单独的请求都被发送到一个服务器,该服务器处理它并提供一个称为response的答案。例如,在客户端和服务器之间有许多实体,统称为代理,它们执行不同的操作并充当网关或缓存。
实际上,在浏览器和处理请求的服务器之间有更多的计算机:有路由器、调制解调器等等。由于 Web 的分层设计,这些隐藏在网络层和传输层中。HTTP 位于应用层之上。尽管对于诊断网络问题很重要,但底层大多与 HTTP 的描述无关。
客户端:用户代理
所述用户代理是作用于用户的代表任何工具。此角色主要由 Web 浏览器执行;其他可能性是工程师和 Web 开发人员用来调试他们的应用程序的程序。
浏览器始终是发起请求的实体。它永远不是服务器(尽管多年来已经添加了一些机制来模拟服务器启动的消息)。
为了呈现一个网页,浏览器发送一个原始请求来获取代表该页面的 HTML 文档。然后解析此文件,发出与执行脚本、要显示的布局信息 (CSS) 以及页面中包含的子资源(通常是图像和视频)相对应的附加请求。然后,Web 浏览器混合这些资源以向用户呈现一个完整的文档,即 Web 页面。浏览器执行的脚本可以在后续阶段获取更多资源,浏览器会相应地更新网页。
网页是超文本文档。这意味着显示文本的某些部分是可以激活(通常通过单击鼠标)以获取新网页的链接,从而允许用户指导他们的用户代理并在 Web 中导航。浏览器在 HTTP 请求中转换这些方向,并进一步解释 HTTP 响应以向用户呈现清晰的响应。
网络服务器
在通信通道的另一侧,是服务器,它根据客户端的请求提供文档。服务器实际上只是一台机器:这是因为它实际上可能是一组服务器,共享负载(负载平衡)或询问其他计算机的复杂软件(如缓存、数据库服务器或电子商务服务器),完全或部分按需生成文档。
服务器不一定是一台机器,但可以在同一台机器上托管多个服务器软件实例。使用 HTTP/1.1 和Host标头,它们甚至可能共享相同的 IP 地址。
代理
在 Web 浏览器和服务器之间,许多计算机和机器中继 HTTP 消息。由于 Web 堆栈的分层结构,其中大部分在传输、网络或物理级别运行,在 HTTP 层变得透明,并可能对性能产生重大影响。那些在应用层操作的通常称为代理。这些可以是透明的,在不以任何方式更改它们的情况下转发它们收到的请求,或者是不透明的,在这种情况下,它们将在将请求传递给服务器之前以某种方式更改请求。代理可以执行多种功能:
缓存(缓存可以是公共的或私有的,如浏览器缓存)
过滤(如防病毒扫描或家长控制)
负载平衡(允许多个服务器为不同的请求提供服务)
身份验证(控制对不同资源的访问)
日志记录(允许存储历史信息)
🏳️🌈HTTP 的基本方面
HTTP 很简单
HTTP 通常被设计为简单易读,即使在 HTTP/2 中通过将 HTTP 消息封装到帧中引入了额外的复杂性。HTTP 消息可以被人类阅读和理解,为开发人员提供了更容易的测试,并降低了新手的复杂性。
HTTP 是可扩展的
HTTP/1.0 中引入的HTTP 标头使该协议易于扩展和试验。甚至可以通过客户端和服务器之间关于新标头语义的简单协议来引入新功能。
HTTP 是无状态的,但不是无会话的
HTTP 是无状态的:在同一连接上连续执行的两个请求之间没有链接。对于试图与某些页面进行连贯交互的用户(例如,使用电子商务购物篮)而言,这立即有可能成为问题。但是,虽然 HTTP 本身的核心是无状态的,但 HTTP cookie 允许使用有状态的会话。使用标头可扩展性,HTTP Cookie 被添加到工作流中,允许在每个 HTTP 请求上创建会话以共享相同的上下文或相同的状态。
HTTP 和连接
连接是在传输层控制的,因此从根本上超出了 HTTP 的范围。虽然 HTTP 不要求底层传输协议是基于连接的;只要求它是可靠的,或者不丢失消息(因此至少会出现错误)。在 Internet 上最常见的两种传输协议中,TCP 是可靠的,而 UDP 则不是。因此,HTTP 依赖于基于连接的 TCP 标准。
在客户端和服务器可以交换 HTTP 请求/响应对之前,它们必须建立 TCP 连接,这个过程需要多次往返。HTTP/1.0 的默认行为是为每个 HTTP 请求/响应对打开单独的 TCP 连接。当多个请求连续发送时,这比共享单个 TCP 连接效率低。
为了缓解这个缺陷,HTTP/1.1 引入了流水线(被证明难以实现)和持久连接:可以使用Connection标头部分控制底层 TCP 连接。HTTP/2 更进一步,通过在单个连接上多路复用消息,帮助保持连接温暖和更高效。
正在进行实验以设计更适合 HTTP 的更好的传输协议。例如,谷歌正在试验快讯 它建立在 UDP 之上,以提供更可靠、更高效的传输协议。
🏳️🌈HTTP可以控制什么
随着时间的推移,HTTP 的这种可扩展特性允许对 Web 进行更多控制和功能。缓存或身份验证方法是 HTTP 历史早期处理的函数。相比之下,放宽原点约束的能力直到2010 年代才被添加。
以下是可通过 HTTP 控制的常见功能列表。
缓存
如何缓存文档可以由 HTTP 控制。服务器可以指示代理和客户端缓存什么以及缓存多长时间。客户端可以指示中间缓存代理忽略存储的文档。
放宽来源限制
为防止窥探和其他隐私侵犯,Web 浏览器强制在 Web 站点之间进行严格分离。只有来自同一来源的页面才能访问网页的所有信息。虽然这样的约束对服务器来说是一种负担,但 HTTP 头可以在服务器端放松这种严格的分离,让文档成为来自不同域的信息的拼凑;甚至可能有与安全相关的原因这样做。
身份验证
某些页面可能受到保护,以便只有特定用户才能访问它们。基本身份验证可以由 HTTP 提供,或者使用WWW-Authenticate和类似的标头,或者通过使用HTTP cookie设置特定会话。
代理和隧道
服务器或客户端通常位于 Intranet 上,并向其他计算机隐藏其真实 IP 地址。HTTP 请求然后通过代理来跨越这个网络障碍。并非所有代理都是 HTTP 代理。例如,SOCKS 协议在较低级别运行。其他协议,如 ftp,可以由这些代理处理。
会话
使用 HTTP cookie 允许您将请求与服务器的状态联系起来。尽管基本 HTTP 是无状态协议,但这会创建会话。这不仅适用于电子商务购物篮,而且适用于允许用户配置输出的任何站点。
🏳️🌈HTTP 流
当客户端想要与服务器(最终服务器或中间代理)通信时,它执行以下步骤:
打开一个 TCP 连接:TCP 连接用于发送一个或多个请求,并接收一个应答。客户端可以打开一个新的连接,重用一个现有的连接,或者打开几个到服务器的 TCP 连接。
发送 HTTP 消息:HTTP 消息(在 HTTP/2 之前)是人类可读的。在 HTTP/2 中,这些简单的消息被封装在帧中,无法直接读取,但原理保持不变。例如
GET / HTTP/1.1 Host: developer.mozilla.org Accept-Language: fr
- 读取服务器发送的响应,如:
HTTP/1.1 200 OK Date: Sat, 09 Oct 2010 14:28:02 GMT Server: Apache Last-Modified: Tue, 01 Dec 2009 20:18:22 GMT ETag: "51142bc1-7449-479b075b2891b" Accept-Ranges: bytes Content-Length: 29769 Content-Type: text/html <!DOCTYPE html... (here comes the 29769 bytes of the requested web page)
关闭或重用连接以进行进一步的请求。
如果激活 HTTP 流水线,则可以发送多个请求,而无需等待完全接收到第一个响应。HTTP 流水线已被证明难以在现有网络中实现,其中旧软件与现代版本共存。HTTP 流水线已在 HTTP/2 中被取代,在帧内具有更强大的多路复用请求。
🏳️🌈HTTP 消息
HTTP 消息,如 HTTP/1.1 及更早版本中所定义,是人类可读的。在 HTTP/2 中,这些消息被嵌入到一个二进制结构中,一个frame,允许优化,如压缩头和多路复用。即使在这个版本的 HTTP 中只发送了原始 HTTP 消息的一部分,每条消息的语义也没有改变,客户端重新构造(虚拟)原始 HTTP/1.1 请求。因此,理解 HTTP/1.1 格式的 HTTP/2 消息很有用。
HTTP 消息有两种类型,请求和响应,每种都有自己的格式。
请求
HTTP 请求示例:
请求由以下元素组成:
一个HTTP方法,通常是一个动词等GET,POST或像一个名词OPTIONS或HEAD定义客户端想要执行操作。通常,客户端想要获取资源(使用GET)或发布HTML 表单的值(使用POST),但在其他情况下可能需要更多操作。
要获取的资源的路径;从上下文中显而易见的元素中剥离的资源 URL,例如没有协议( http://)、域(此处为developer.mozilla.org)或 TCP端口(此处为80)。
HTTP 协议的版本。
为服务器传达附加信息的可选标头。
响应
一个示例响应:
响应由以下元素组成:
他们遵循的 HTTP 协议的版本。
一个状态代码(status code),表示如果请求成功,或没有,以及为什么。
状态消息,状态代码的非权威性简短描述。
HTTP标头,就像请求的标头一样。
可选地,包含获取的资源的正文。
🏳️🌈基于 HTTP 的 API
最常用的基于 HTTP 的API是XMLHttpRequestAPI,它可以用于在用户代理和服务器之间交换数据。现代Fetch API提供了相同的功能和更强大、更灵活的功能集。
另一个 API,服务器发送事件( server-sent events),是一种单向服务,它允许服务器使用 HTTP 作为传输机制向客户端发送事件。
使用该EventSource接口,客户端打开一个连接并建立事件处理程序。客户端浏览器自动将到达 HTTP 流的消息转换为适当的Event对象,将它们传递给已为事件注册的事件处理程序(type如果已知),或者onmessage如果没有建立特定类型的事件处理程序,则传递给事件处理程序。
💬结论
HTTP 是一种易于使用的可扩展协议。客户端-服务器结构与添加标头的能力相结合,允许 HTTP 与 Web 的扩展功能一起发展。
尽管 HTTP/2 增加了一些复杂性,但通过在帧中嵌入 HTTP 消息来提高性能,消息的基本结构自 HTTP/1.0 以来一直保持不变。会话流保持简单,允许使用简单的HTTP 消息监视器对其进行调查和调试。