HTTP 概述

[ 原来的网页是可以选择“简体中文的”,没看见……,已经自己翻译了,就这样好了 ,翻译了好久]

HTPP是一种 client-server 协议,意味着请求由接收端(一般是Web浏览器)发起,所获取的各种不同的子文档如文本、布局描述、图像、视频、脚本等重建成一个完整的文档。

在这里插入图片描述
客户端和服务器通过交换单个消息(而不是数据流)进行通信。由客户端(通常是Web浏览器)发送的消息称为请求(Request), 而由服务器作为回答而发送的消息称为响应(Response)。

HTTP是一种可扩展协议,设计时间是20世纪90年代早期,随着时间的推移不断发展。 HTTP是通过TCP或通过TLS加密的TCP连接发送的一种应用层协议,但理论上任何可靠的传输协议都可以使用。 由于其可扩展性,它不仅用于获取超文本文档,还用于获取图像和视频或将内容发布到服务器,例如HTML表单结果。 HTTP还可用于获取文档的一部分以按需更新Web页面。

在这里插入图片描述

1 基于HTTP系统的组成部分

HTTP是客户端 - 服务器协议:请求由一个实体(用户代理 user-agent 或 proxy)发送。 大多数情况下,用户代理是一个Web浏览器,但它可以是任何东西,例如爬行Web以填充(populate)和维护搜索引擎索引的机器人。

每个单独的请求都被发送到服务器,服务器将处理请求并提供一个称为响应的回答。 在该请求和响应之间,存在众多实体,统称为代理(proxy),这些代理执行不同的操作, 例如充当网关或高速缓存(cache)。
在这里插入图片描述
现实中,浏览器和处理请求的服务器之间有着更多的计算机:有路由器、调制解调器等。 多亏了Web的分层设计,这些都隐藏在网络层和传输层中。 HTTP位于应用层(application layer)的顶部。 虽然对于网络问题的诊断很重要,但下面的各层与HTTP的描述基本无关。

1.1 客户端:用户代理(Client: the user-agent)

用户代理是代表用户执行操作的任意工具,这一角色主要由Web浏览器执行; 少数例外情况下是程序,工程师和Web开发人员用这些程序来调试他们自己的应用程序。

浏览器 永远 是发起请求的实体,它永远不会是服务器(尽管这些年来已经添加了一些机制来模拟服务器发起的消息)。

为了呈现Web页面,浏览器发送原始请求以从页面获取HTML文档。 然后,它解析此文件,获取与执行脚本、显示的布局信息(CSS)以及页面中包含的子资源(通常是图像和视频)相对应的其他请求。 然后,Web浏览器混合这些资源以向用户呈现一个完整的文档,即Web页面。 被浏览器执行的脚本能够在以后的阶段获取更多资源,浏览器会相应地更新网页。

We页面(网页)是超文本文档。 这意味着显示文本的某些部分是可以激活的链接(通常通过单击鼠标)可以用来获取新的Web页面,允许用户指示(direct)其用户代理并在Web上导航。 浏览器将这些指示翻译成HTTP请求,并进一步解释HTTP响应以向用户呈现明确的响应。

1.2 Web服务器 (The Web server)

在通信信道的另一端是服务器,它根据客户端的请求提供文档。 服务器以虚拟的方式只呈现为一台机器:这是因为它实际上可能是共享负载(负载平衡)服务器的集合,或是询问(interrogating )其他计算机(如缓存、数据库服务器、电子商务服务器等)的一个复杂软件,按需完全或部分生成文档。
服务器不一定是单个机器,但在同一台机器上可以托管(host)多个服务器。 使用HTTP/1.1和Host 头,这些服务器甚至可以共享相同的IP地址。

1.3 代理(Proxies)

在Web浏览器和服务器之间,大量计算机和机器转发(relay)HTTP消息。 由于Web堆栈的分层结构,绝大多数转发操作都在传输层、网络层或物理层进行,在HTTP层变得透明,并可能对性能有着重大影响。 在应用层操作的那些通常称为代理。 这些可以是透明的,也可能不是(通过它们更改请求 changing requests going through them),并可能执行大量功能:

  • 进行缓存(缓存可以是公共的或私有的,如浏览器缓存)
  • 过滤(如防病毒扫描,家长控制,…)
  • 负载平衡(允许多个服务器为不同的请求提供服务)
  • 身份验证(控制对不同资源的访问)
  • 日志(logging)(允许存储历史信息)

2 HTTP的基本方面

2.1 HTTP 是简单的

在HTTP/2中,引入了将HTTP消息封装到帧中,即使由于这点增加了复杂性,但HTTP的设计一贯力求简单,并且要有可读性。HTTP消息可以被人们读取并理解,为开发者提供更简单的测试,并为初学者降低复杂性。

2.2 HTTP 可扩展

在HTTP /1.0中引入的HTTP头使该协议易于扩展和实验,甚至可以通过客户端和服务器之间关于一种新头的语义的简单协议来引入新的功能。

2.3 HTTP 无状态,但不是无会话(stateless, but not sessionless)

HTTP是无状态的:在同一连接上连续执行的两个请求之间没有链接。 对于试图与某些页面连续交互的用户而言,这存在明显的问题,例如,使用电子商务购物车。 虽然HTTP的核心本身是无状态的,但HTTP cookie允许使用有状态的会话(session)。 使用头的可扩展性,HTTP Cookie被添加到工作流程中,允许在每个HTTP请求上创建会话以共享相同的上下文或相同的状态。

2.4 HTTP 与连接

连接在传输层受到控制,因此从根本上超出了HTTP的范围。 虽然HTTP不要求底层传输协议是基于连接的;只要求它是可靠的,或者不丢失消息(至少要报告错误)。 在Internet上最常见的两种传输协议中,TCP是可靠的,而UDP则不是。 HTTP因此依赖于基于连接的TCP标准,即使并不总是需要连接。

在客户端和服务器可以交换HTTP请求/响应对之前,它们必须建立TCP连接,这个过程需要多次往返。 HTTP/1.0的默认行为是为每个HTTP请求/响应对打开单独的TCP连接。 当密集连续发送多个请求时,这比共享单个TCP连接的效率要低。

为了改善这个缺陷,HTTP / 1.1引入了流水线操作(pipelining,事实证明难以实现)和持久连接:可以使用Connection头部分控制底层TCP连接。 HTTP/2 更进一步,通过在单个连接上复用消息(multiplexing messages),有助于使连接更高效。

设计更适合HTTP的更好的传输协议的实验正在进行中, 例如谷歌正在试验基于UDP的QUIC,以提供更可靠和有效的传输协议。

3 HTTP 所能控制的

随着时间的推移,HTTP的这种可扩展特性允许它在Web上实现更多的控制和功能。缓存或身份验证是HTTP早期历史中处理的功能。相对而言,放宽原点约束(relax the origin constraint, 我搜不到标准翻译,自行翻译) 的功能是在2010年代才添加的。

以下是可通过HTTP可控制的常用功能列表。

  • 高速缓存
    如何缓存文档可以通过HTTP控制。服务器可以指示代理和客户端,缓存哪些内容,缓存多久。客户端可以指示中间缓存代理忽略存储的文档。
  • 放宽原点约束
    为防止窥探和其他隐私入侵,Web浏览器强制要求网站之间严格分离。只有来自同一来源的页面才能访问网页的所有信息。虽然这种约束对服务器来说是一种负担,但HTTP头可以放宽服务器端的这种严格分离,允许使用来自不同域的信息进行拼凑得到文档(这样做甚至可能是出于和安全相关的原因)。
  • 认证
    某些页面可能受到保护,因此只有特定用户才能访问它。 HTTP可以提供基本的认证:要么使用WWW-Authenticate和类似的头,或者通过使用HTTP cookie设置特定会话。
  • 代理和隧道(Proxy and tunneling)
    服务器和/或客户端通常位于Intranet上,并将其真实的IP地址隐藏起来。然后,HTTP请求通过若干代理穿过此网络屏障。并非所有代理都是HTTP代理。例如,SOCKS协议在较低级别操作。其他协议如FTP可以由这些代理处理(The SOCKS protocol, for example, operates at a lower level. Others, like ftp, can be handled by these proxies. 什么意思我不确定)。
  • 会话
    使用HTTP cookie允许您将请求与服务器的状态链接。尽管基本的HTTP是无状态协议,但这会创建会话。这不仅适用于电子商务购物车,也适用于允许用户配置输出的任何站点。

4 HTTP 流程

当客户端想要与服务器通信时,无论是最终服务器还是中间代理都会执行以下步骤:

  1. 打开一个TCP连接:TCP 连接将用于发送一个或多个请求,并接收回答。 客户端可能打开一个新的连接,或者重用已有的连接,或打开与服务器的多个TCP连接。
  2. 发送一个HTTP消息:HTTP消息(在HTTP/2之前)是人类可读的。 使用HTTP/2,这些简单的消息被封装在帧中,使得它们无法直接读取,但原理保持不变。
    在这里插入图片描述
  3. 读取由服务器发送的响应:
    在这里插入图片描述
  4. 为其他请求关闭或重用连接

如果激活HTTP流水线操作,则可以发送多个请求,而无需等待完全接收到第一个响应。 事实证明,HTTP流水线技术很难在现有网络中实现,因为在现有网络中旧的软件与现代版本共存。 在HTTP/2中,HTTP流水线已经被取代,转而使用更健壮的帧内复用请求技术( HTTP pipelining has been superseded in HTTP/2 with more robust multiplexing requests within a frame)。

5 HTTP 消息

HTTP/1.1和早期的HTTP消息都是人类可读的。 在HTTP/2中,这些消息被嵌入到一个新的二进制结构中,即帧内,允许如压缩头(header)及复用(multiplexing)之类的优化。 即使在此版本的HTTP中仅发送了原始HTTP消息的一部分,每个消息的语义也保持不变,并且客户端(虚拟地)重建原始HTTP/1.1请求。 因此,理解格式为HTTP/1.1的HTTP/2消息是有用的。

有两种类型的HTTP消息:请求和响应,两种消息都有自己的格式。

5.1 请求

一个HTTP 请求的例子:

在这里插入图片描述
请求包含以下元素:

  • 一个HTTP方法,通常是一个定义了客户端想要执行的操作的单词,例如像GETPOST的动词,或类似OPTIONSHEAD的名词。 典型情况下,客户端想要获取资源(使用GET)或发布HTML表单的值(使用POST),在其他情况下可能需要更多操作。
  • 要获取的资源的路径; 从上下文中显而易见的元素中剥离的资源的URL,例如没有协议(http://),域(此处为 developer.mozilla.org)或TCP端口(此处为80)。
  • HTTP协议的版本。
  • 可选的头,用于为服务器传达其他信息。
  • 或者一个正文(body),对于一些像POST这样的方法,类似于响应中的方法,包含了发送的资源。

5.2 响应

一个响应的例子:
在这里插入图片描述
响应由如下元素构成:

  • 响应所遵循的HTTP协议的版本。
  • 状态代码,指示请求是否成功,以及原因。
  • 状态消息,状态代码的非权威性简短描述。
  • HTTP头,与请求的头类似。
    (可选)包含获取到的资源的正文(body)。

6 基于HTTP的API

基于HTTP的最常用API是XMLHttpRequest,可用于在用户代理和服务器之间交换数据。 现代的Fetch API提供了相同的功能,具有更强大更灵活的功能集。

另一个API,即server-sent events,是一种单向服务,允许服务器使用HTTP作为传输机制向客户端发送事件。 客户端使用EventSource接口打开一个连接并建立事件处理程序。 客户端浏览器自动将到达HTTP流的消息转换为适当的Event对象,将它们传递给已经为事件的type注册的事件处理程序(如果已知),或者如果没有特定于类型的事件处理程序被建立,则将它们传递给onmessage事件处理程序。

7 总结

HTTP 是一种易于使用的可扩展协议。客户端-服务器 的结构,加上可简单添加协议头的能力,使HTTP可与Web不断扩展的功能一起发展。

虽然 HTTP/2因为嵌入了HTTP消息到帧里以改善性能而增加了一些复制性,但消息的基本结构自HTTP/1.0以来一直是一样的。会话流仍然很简单,这使得它可以通过一个简单的HTTP消息监视器进行检查和调试。


[1] https://developer.mozilla.org/en-US/docs/Web/HTTP/Overview

展开阅读全文

没有更多推荐了,返回首页