30

你必须知道的HTTP基本概念

文章首发于:https://dunizb.com
原文连接:https://dunizb.com/2017/12/08/You-have-to-know-the-basic-HTTP-concepts/

从本文你将看到:HTTP是干嘛用的?怎样和服务器通信?HTTP的基本性质?HTTP能控制什么?基于HTTP三大组件系统?HTTP 和 TCP 之间的关系?HTTP 协议如何使用 TCP 连接?

本文没什么高深的东西,就是把一些概念整理了一下,大牛可以飘过,不喜勿喷

一、什么是HTTP

HTTP是干嘛用的?

HTTP学名叫做超文本传输协议,是一个网络协议。

是专门用来帮你传输诸如 HTML 的超媒体文档等 Web 内容滴。因为 HTML 本身就是超文本标记语言,HTML 中不仅有文本还有图片、音视频等内容,所以用来传输它的协议当然就叫超文本传输协议了。

比如你访问俺的博客的主页,浏览器地址栏会出现如下的网址:http://dunizb.com/,加了粗体的部分就是指 HTTP 协议。大部分网站都是通过 HTTP 协议来传输 Web 页面、以及 Web 页面上包含的各种东东(图片、CSS 样式、JS 脚本)。

它基于 TCP/IP 的应用层协议。它被设计用于Web浏览器和Web服务器之间的通信,但它也可以用于其他目的。

它是 Web 上数据交换的基础,是一种 client-server 协议,也就是说请求通常是由像浏览器这样的接受方发起的。一个完整的 web文档是由不同的子文档重新组建而成的,像是文本、布局描述、图片、视频、脚本等等。

怎样和服务器通信?

  1. HTTP遵循经典的客户端-服务端模型,客户端打开一个连接以发出请求,然后等待它收到服务器端响应。 HTTP是无状态协议,意味着服务器不会在两个请求之间保留任何数据(状态)。
  2. 客户端和服务端通过交换各自的消息(与数据流正好相反)来进行交互。通常由像浏览器这样的客户端发出的消息叫做 requests,那么被服务端回应的消息就叫做 responses。

HTTP 被设计于上20世纪90年代初期,是一种可扩展性的协议。它是应用层的协议,虽然理论上它可以通过任何可靠的传输协议来发送,但是它还是通过 TCP,或者是 TLS-加密的TCP连接来发送。因为它很好的扩展性,时至今日它不仅被用来传输超文本文档,还用来传输图片、视频或者向服务器发送如 HTML 表单这样的信息。HTTP 还可以根据网页需求,来获取部分web文档的内容来更新网页。

HTTP遵循经典的客户端-服务端模型,客户端打开一个连接以发出请求,然后等待它收到服务器端响应。 HTTP是无状态协议,意味着服务器不会在两个请求之间保留任何数据(状态)。虽然通常基于TCP / IP层,但可以在任何可靠的传输层上使用;也就是说,一个不会静默丢失消息的协议,如UDP。

二、HTTP的基本性质

总述:HTTP是简单的、可扩展、无状态的

HTTP 是简单的

即便在HTTP/2中把HTTP消息封装到了frames中,HTTP大体上还是被设计成可读的而且简单的。HTTP的消息能够让人读懂且明白它的意思,还允许简单的测试,放低了门槛,更有利于新来者了解。

HTTP 是可扩展的

在HTTP/1中就出现了, HTTP headers 让协议扩展变得非常容易。只要服务端和客户端在新的headers上语义达成一致,新的功能就可以轻松地被加进来。

HTTP 是无状态,有会话的

HTTP是无状态的:在同一个连接中,两个成功执行的请求之间是没有关系的。这就带来了一个问题,用户没办法在一个网站进行连续的交互,比如在一个电商网站里,用户把某个商品加入了购物车中,换了一个页面后再次添加商品,两次添加商品的请求没有联系,浏览器无法知道最终用户都选择了哪些商品。而用HTTP的头部扩展,HTTP Cookies就可以解决这个问题(将在后面介绍)。把Cookies添加到头部中,创建一个会话来让每次请求都能共享相同的上下文信息,相同的状态。而HTTP的核心是无状态的,cookies的使用可以创建有状态的会话。

三、HTTP能控制什么

多年以来,HTTP良好的扩展性控制着越来越多Web的功能。缓存和认证方式很早就可以由HTTP来控制了。另一方面,对同源同域的限制到2010年才有所改变。

下面就是可以用HTTP来控制的常见特性。

缓存

文档怎么缓存能够通过HTTP来控制。服务端能告诉代理和客户端什么需要被缓存,缓存多久,而客户端能够根据请求条件首部字段(如If-Modified-Since、If-Match等)来忽略存储的文档。

开放同源限制

为了防止网络窥听和其它的隐私泄漏,浏览器强制对Web网站做了分割限制。只有来自于相同来源的网页才能够获取网站的全部信息。这样的限制有时反而成了负担,HTTP可以通过修改头部来开放这样的限制,因此web文档可以是由不同域下的信息拼接成的(在某些情况下,这样做还有安全因素考虑在里面)。

认证

一些页面能够被保护起来,仅让特定的用户进行访问。基本的认证功能可以直接通过HTTP提供,使用Authenticate相似的头部就可以,或者用HTTP cookies来设定指定的会话。

代理和隧道

通常情况下,服务器和/或客户端是处于内网的,对其它(外网)隐藏其真实 IP 地址。因此 HTTP 请求就要通过代理越过这个网络屏障。但并非所有的代理都是 HTTP 代理。例如,SOCKS协议的代理就运作在更底层。一些像 ftp 其它的协议也能够被它们处理。

Cookies
Cookies用一个服务端的状态连接起了每一个请求。这就创建了会话,虽然基本的HTTP是无状态协议。这很有用,不仅是因为能用到购物车这样的电商业务上,更是因为,它使得任何网站都能够配置页面展现的东西了。

四、基于HTTP三大组件系统

客户端:user-agent

严格意义来说,user-agent 就是任何能够为用户发起行为的工具。但实际上,这个角色通常都是由浏览器来扮演。对于发起请求来说,浏览器总是作为发起一个请求的实体,而永远不是服务器(虽然一些机制已经能够模拟服务器发起请求的消息了)。

Web服务端

在上述通信过程的另一端,就是一个Web Server来服务并提供客户端请求的文档。Server只是虚拟意义上:它可以是许多共同分担负载(负载平衡)的一组服务器组成的计算机群,也可以是一种复杂的软件,通过向其他计算机发起请求来获取部分或全部资源的软件。

Server不再只是一个单独的机器,它可以是在同一个机器上装载的许多服务之一。在HTTP/1.1和Host头部中,它们甚至可以共享同一个IP地址。

Proxies 代理

在浏览器和服务器之间,有许多计算机和其他设备转发了HTTP的消息。因为Web栈层次结构的原因,它们大多数都出现在传输层、网络层和物理层上,对于HTTP的应用层来说就是透明的(虽然它们可能会对应用层的性能有重要影响)。而还有一部分表现在应用层上的,就叫做proxies了。Proxies既可以表现得透明,又可以不透明(看请求是否通过它们),主要表现在这几个功能上:

  • 缓存(可以是公开的或是私有的,像浏览器的缓存)
  • 过滤(像反病毒扫描,家长监护)
  • 负载均衡,让多个服务器服务不同的请求
  • 对不同资源的权限控制
  • 登陆,允许存储历史信息

每一个发送到服务器的请求,都会被服务器处理并且返回一个消息,也就是response。在client与server之间,还有许许多多的被称为proxies的实体,他们的作用与表现各不相同,比如有些是网关,还有些是caches等。
Client-server-chain

实际上,在一个浏览器和处理请求的服务器之间,还有计算机、路由器、调制解调器等等许多实体。由于Web的层次设计,那些在网络层和传输层都不可见了。HTTP是在最上层应用层中的,虽然下面的层次对分析网络问题非常重要,但是对HTTP的描述来说,这些大多数都是不相关的。

五、HTTP 和 TCP 之间的关系

前面说过,HTTP是基于 TCP/IP 的,简单地说,TCP 协议是 HTTP 协议的基石——HTTP 协议需要依靠 TCP 协议来传输数据。

在网络分层模型中,TCP 被称为“传输层协议”,而 HTTP 被称为“应用层协议”。有很多常见的应用层协议是以 TCP 为基础的,比如“FTP、SMTP、POP、IMAP”等。

TCP 被称为“面向连接”的传输层协议。关于它的具体细节,俺就不展开了(否则篇幅又失控了)。你只需知道:传输层主要有两个协议,分别是 TCP 和 UDP。TCP 比 UDP 更可靠。你可以把 TCP 协议想象成某个水管,发送端这头进水,接收端那头就出水。并且 TCP 协议能够确保,先发送的数据先到达(与之相反,UDP 不保证这点)。

六、HTTP 协议如何使用 TCP 连接?

HTTP 对 TCP 连接的使用,分为两种方式:俗称“短连接”和“长连接”(“长连接”又称“持久连接”,洋文叫做“Keep-Alive”或“Persistent Connection”)

假设有一个网页,里面包含好多图片,还包含好多 外部的 CSS 文件和 JS 文件。在“短连接”的模式下,浏览器会先发起一个 TCP 连接,拿到该网页的 HTML 源代码(拿到 HTML 之后,这个 TCP 连接就关闭了)。然后,浏览器开始分析这个网页的源码,知道这个页面包含很多外部资源(图片、CSS、JS)。然后针对 每一个 外部资源,再分别发起一个个 TCP 连接,把这些文件获取到本地(同样的,每抓取一个外部资源后,相应的 TCP 就断开)
相反,如果是“长连接”的方式,浏览器也会先发起一个 TCP 连接去抓取页面。但是抓取页面之后,该 TCP 连接并不会立即关闭,而是暂时先保持着(所谓的“Keep-Alive”)。然后浏览器分析 HTML 源码之后,发现有很多外部资源,就用刚才那个 TCP 连接去抓取此页面的外部资源。

在 HTTP 1.0 版本,默认使用的是“短连接”(那时候是 Web 诞生初期,网页相对简单,“短连接”的问题不大).

到了1995年底开始制定 HTTP 1.1 草案的时候,网页已经开始变得复杂(网页内的图片、脚本越来越多了)。这时候再用短连接的方式,效率太低下了(因为建立 TCP 连接是有“时间成本”和“CPU 成本”滴)。所以,在 HTTP 1.1 中,默认采用的是“Keep-Alive”的方式。

七、一些术语

资源(resource)

Web资源是使用URL指向的Web内容。

  • 内容可以是静态的,如:文本文件、HTML文件、JPEG文件。
  • 或者是动态的内容。如:摄像头的实时采集软件生成的动态影像,用户填写的电子网站订单。

资源类型

Web服务器会为所有HTTP资源赋予一个类型,以便于HTTP软件处理消息主体。如,用 text/html 标记 html。可以再看两个案例:

  • text/plain :ASCII文本文档
  • image/jpeg :JPEG版本的图片

非常多的资源类型和文本标记的对应关系,一起构成了一个超长的清单,并且由RFC 2045标准化。此标准被称为MIME。MIME是Multipurpose Internet Mail Extension的缩写。虽然名称很长,但是含义简单,就是用来指定消息内的实体类型的。之所以有Mail字样,是因为最初设计是为了Mail的异构系统交换文档的。

资源标示符

URL是一种资源位置标示方法。URL描述了一个资源在服务器上的位置。这就是一个合法的URL:http://example.com/part/index...

  • 第一部分:方案(scheme)。指明了访问资源所使用的协议类型。这部分通常是HTTP协议(http://)
  • 第二部分:服务器地址(比如,example.com)。
  • 其余部分指定了Web服务器上的某个资源(比如,/part/index.htm)。

当在地址栏输入此资源名并回车后,用户代理会把URL解析,把必要的信息以HTTP协议的要求,打入请求消息内。以http://www.example.com/index....,变成

GET index.html HTTP/1.1
host:www.example.com
空行

打开到www.example.com的tcp连接,并发送此请求消息给服务器,然后等待服务器响应并解析显示给用户。

更多URL、URI、URN详细推荐阅读:《你知道URL、URI和URN三者之间的区别吗?》

HTTP事务

一个HTTP事务由一条请求消息和一个响应消息构成。

HTTP方法

HTTP支持几种不同的请求命令,这些命令被称为HTTP方法(HTTP method)。每条HTTP请求报文都包含一个方法。

状态码

每条HTTP响应消息返回时都会携带一个状态码。状态码是一个三位数字的代码,告知客户端请求是否成功,或者是需要采取其他行动。

消息

从Web客户端发往Web服务器的HTTP报文称为请求消息。从服务器发往客户端的消息称为响应消息。HTTP报文包括三部分:

起始行
首部字段 
主体

如发送一个hello.htm 的资源给客户端,请求消息是:

GET /hello.html HTTP/1.1

请求消息只有起始行,指明使用的HTTP方法、资源的URL,以及协议的版本。没有首部字段和主体。

响应消息为:

HTTP/1.1 200 OK
X-Powered-By: Express
Content-Type: text/html; charset=utf-8
Content-Length: 22
ETag: W/"16-FmHX0hamHjYkHeAP/7PfzA"
Date: Thu, 03 Dec 2015 09:54:01 GMT
Connection: close

<h1>Hello, World!</h1>

这个消息第一行为起始行,指明协议版本、状态码(200表示成功)和状态说明(OK)。接下来一直到空行之间都是首部字段,用来说明服务器、资源类型、内容长度、生成文档时间等。空行后就是主体,这里就是一个html文件的内容。实际上,主体可以承载任何内容,而不限于文本。

总结

HTTP是一个简单快速、灵活、无连接、无状态的超文本传输协议。

HTTP是很简单可扩展的一种协议。结合了轻松添加头部信息能力的Client-server结构使得HTTP可以和Web的功能扩充一同发展。

即使HTTP/2为了提高性能把HTTP报文嵌到帧中这一举措增加了复杂度,但是从Web应用的角度来看,报文的基本结构是没有变化的,从HTTP/1.0发布起就是相同的。


关于HTTP,如果你不想啃大部头的《HTTP权威指南》,那么强烈建议你阅读刘传君的图灵电子书《HTTP小书》,准能帮你节省不少时间,只要9块钱!戳这里:http://www.ituring.com.cn/book/1791

HTTP小书


参考资料:


杭州程序员张张
11.8k 声望6.7k 粉丝

Web/Flutter/独立开发者/铲屎官