文章首发于: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文档是由不同的子文档重新组建而成的,像是文本、布局描述、图片、视频、脚本等等。
怎样和服务器通信?
- HTTP遵循经典的客户端-服务端模型,客户端打开一个连接以发出请求,然后等待它收到服务器端响应。 HTTP是无状态协议,意味着服务器不会在两个请求之间保留任何数据(状态)。
- 客户端和服务端通过交换各自的消息(与数据流正好相反)来进行交互。通常由像浏览器这样的客户端发出的消息叫做 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等。
实际上,在一个浏览器和处理请求的服务器之间,还有计算机、路由器、调制解调器等等许多实体。由于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://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。