不管是前端工程师、后端工程师、客户端工程师仍是测试工程师,HTTP 协议都是咱们天天须要打交道的东西。可是对于大多数人来讲,也包括我本身,对于 HTTP 协议的学习都是碎片化且不成体系的。然而 HTTP 协议又如此重要,性能优化中一个很是重要的部分就是网络优化,全面理解 HTTP 协议就可让咱们的页面更快,体验更好。前端
同时,网络也是每个程序员都应该掌握的底层知识,它与数据结构与算法、操做系统、编译原理等被称为程序员的内功,掌握了内功,咱们才能在职场上走的更远。HTTP 协议属于网络协议中重要的一环,所以须要咱们全面而深刻的掌握它。git
其实系统学习 HTTP 协议的材料很是少,像 《HTTP 权威指南》这样的大部头年代也很是久远,因此我最近的学习套路,是在阅读 HTTP/1.1 版本 RFC7230 文档的同时,在极客时间上阅读网络相关的几个专栏。程序员
而在最近的深刻学习中我也发现, HTTP 协议的概念众多,经常看了后面忘了前面。就像学习金字塔理论所指出的,经过听讲和阅读能记忆的知识实际上是不多的,并且俗话说的好 —— “不动笔墨不读书”,我也但愿经过一个系列的写做,更快更好地掌握 HTTP 协议。github
本文是系列文章的第一篇 —— 《HTTP 与网络基础》。算法
1989 年,欧洲核子研究组织(CERN)的蒂姆·博纳斯-李(Tim Berners-Lee)博士提出一个构想:借助多文档之间相互关联造成的超文本(HyperText),连成可参阅的 WWW(World Wide Web,万维网),以帮助远隔两地的研究者们共享知识。后端
在这个构想中,他提出了 3 项 WWW 构建的关键技术:浏览器
1990 年 11 月,CERN 研发出世界上第一台 Web 服务器和 Web 浏览器,远隔两地的人们终于能够在网络上共享信息了,但受限于当时网络的速度与技术的限制,网络上的绝大多数资源都是纯文本,因此诞生之初的 HTTP 仅提供 GET 方法,从服务器上获取 HTML 文档,设计至关简陋。此时的 HTTP 协议版本,后来被称为 HTTP/0.9 ,但它并无做为正式的标准被创建,HTTP/0.9 也含有 HTTP/1.0 以前版本的意思。缓存
1993 年 1 月,NCSA(National Center for Supercomputer Applications,美国国家超级计算机应用中心)研发出 Mosaic 浏览器,它之内联等形式显示 HTML 图像,人们终于能够看到图文混排的 HTML 文档了。性能优化
1995年,网景公司发布了 Netscape Navigator 1.0,微软发布了 IE 1.0 和 2.0,随后服务器软件 Apache 以及 HTML 2.0 版本的出现,让 Web 技术日新月异的增加。HTTP 也在 Web 技术飞速的发展中,不断地迭代。1996 年 HTTP/1.0 版本正式发布,记载于 RFC1945。虽然说是早期版本,可是与如今最经常使用的 HTTP/1.1 版本差距并非很大,因此该版本仍然在一些公司使用。服务器
1995 年后,网景和微软的浏览器大战愈演愈烈,两家公司对当时发展中的 Web 标准视而不见,致使写 HTML 页面时,必须考虑兼容性问题,让不少人头痛不已。但不能否认的是,浏览器大战也推进了 Web 的发展。1999 年,HTTP/1.1 发布 RFC2612,虽然相对于 HTTP/1.0 来讲改变不大,但却在往后的 20 多年里所向披靡,时至今日,HTTP/1.1 依然是绝大多数公司仍在使用的 HTTP 版本。
说了这么多 HTTP 的发展历史,那么 HTTP 究竟是什么?
在 HTTP/1.1 最新标准 RFC7230 中,是这么定义 HTTP 的:
The Hypertext Transfer Protocol (HTTP) is a stateless application-level request/response protocol that uses extensible semantics and self-descriptive message payloads for flexible integration with network-based hypertext information systems.
HTTP 协议是一种无状态的、处于应用层的、以请求/应答方式运行的协议,使用可扩展的语义和自描述的信息格式,与基于网络的超文本信息系统灵活的相互做用。
在上面的定义中,有几个关键词是须要咱们特别留意的,理解了这几个关键词,就能够掌握 HTTP 协议的本质。
无状态是指每个请求/响应是被隔离的,后一个请求没法依赖前一个请求中的信息、字段等。也就是说 HTTP 协议不会对请求和响应之间的通讯状态进行保存,不作持久化处理。好比,当用户 A 登陆后,发起一个查询本身购物车中商品的请求,服务器会给出相应的响应。然而当用户 A 再次发起一个请求,想要查询本身信息的时候,服务器没法依据上一次请求判断用户 A 的身份,必须将用户身份再次告知服务器才能够。
应用层面向具体的应用提供数据。应用层的协议不少,好比 DNS 专门处理域名及 IP 的相互转换;FTP 专门传输文件;SMTP 专门发送邮件等等。而 HTTP 也是众多应用层协议中的一种,可是它却几乎能够传递一切东西,因此历经 20 余年的发展,依旧经久不衰,覆盖面及广
HTTP 的工做方式是由请求方首先创建链接发起请求,应答方接收到请求后才能作出响应,必须遵循”发起 - 接收“的工做模式。
高度可扩展的语义,也是 HTTP 协议经久不衰的一个重要缘由。从最先的只支持 GET 请求的 HTTP/0.9 版本到如今最经常使用的 HTTP/1.1,HTTP 协议逐渐增长了不少请求方法、版本号、状态码等等。并且只要服务端和客户端就 HTTP headers 达成语义一致,新功能就能够被轻松加入进来。
咱们能够本身描述消息,从本身描述的消息中咱们能够知道传递的是文本、图片、音频仍是视频。
所谓超文本,就是 HTTP 协议不只能够传输文本,还能够传输图片、音频、视频以及超连接等复杂的数据。
OSI(Open System Interconnection Reference Model),开放式系统互联通讯参考模型,也就是咱们常说的 7 层模型。从它的名称就能够看出来,OSI 只是一个供参考的概念模型,它从未被真正的实现。
OSI 的 7 层,从上至下分别是:
L7 应用层:解决业务问题,面向具体的应用传输数据;
L6 表示层:将消息转换为应用层能够读取的消息;
L5 会话层:创建会话、握手、维持网络的链接状态;
L4 传输层:包括咱们熟悉的 TCP 与 UDP 等,解决进程与进程之间的通信;
L3 网络层:主要包括 IP 协议,负责将报文从因特网上的一个主机发送到另外一个主机上;
L2 数据链路层:工做在局域网中,使用 MAC 地址标记网络上的设备,如路由器,而后将报文转到主机上;
L1 物理层:电缆、光纤等。
OSI 只是一个概念模型,而日常工做咱们最经常使用的仍是 TCP/IP 模型。TCP/IP 模型其实就是 OSI 模型的简化版本,也就是咱们平时所说的 4 层模型。
TCP/IP 的 4 层,由上至下分别是:
经过上图咱们能够看出,其实 TCP/IP 模型与 OSI 模型十分类似,主要是省略了表示层、会话层与物理层的实现。这里每一层的功能实际上与对应的 OSI 模型十分相似,因此就再也不罗列了。下面是一张 OSI 模型与 TCP/IP 模型的层级对照图,你们能够经过对照图来总结 TCP/IP 模型中各层的职责。
网络分层的好处是,每一次层都只负责本身的任务,其余层的事情彻底不须要考虑,层次之间交互的时候,只须要调用接口就能够了。当某一层须要修改的时候,也彻底不影响其余的功能。固然,有优点就必定有劣势,每一次进行网络通讯的时候,都须要由上至下,一层一层的传递信息,反过来,又要一层一层的向上传递,对于性能的影响是比较大的。
DNS(Domain Name System)协议与 HTTP 协议同样,位于应用层,提供域名到 IP 地址之间的解析服务。主机与主机间的通讯是经过 IP 完成的。可是 IP 地址是一串数字,好比 192.168.1.100,人们很难去记忆,因此就有了域名。相比于 IP 地址来讲,域名是有意义的单词,更容易被人们记住,可是计算机却没法理解,而 DNS 就能够提供将咱们在浏览器的地址栏输入的域名解析为对应 IP 地址的服务(逆向反查也能够)。
以 www.baidu.com 为例,从左到右层级逐渐升高,最右侧的 com 称为顶级 DNS 服务器,中间的 baidu.com 称为权威域名服务器,最左侧的 www 就是对应的主机。由于全世界互联网上的电脑实在太多了,因此 DNS 服务器必需要进行分布式管理,而且要承受高并发。所以,DNS 服务器被设计成了一种树状的层次结构,解析域名时逐层递归查询,而最顶端是 13 组根 DNS 服务器。
除此以外,还须要众多的缓存来处理域名与 IP 地址间的映射关系,以提升访问速度。如浏览器缓存、本地 hosts 缓存、系统缓存。
当咱们在浏览器的地址栏中输入一个域名时,一般查找域名与 IP 地址的映射关系的顺序是:
浏览器缓存
本地 hosts
系统缓存
根 DNS 服务器(看到是 com 结尾的,就告诉 com 顶级 DNS 服务的 IP 地址)
顶级 DNS 服务器(看到是 baidu.com,告诉 baidu.com 的权威 DNS 服务器的 IP 地址)
权威 DNS 服务器(查找对应主机,告诉 www.baidu.com 的真正 IP 地址)
TCP 协议位于传输层,提供可靠的字节流服务,保证了数据的完整性以及不丢失。
为了确保数据完整的到达目标处,TCP 协议采用了三次握手的策略:
发送端首先发送一个带 SYN 标志的数据包给接收端;
接收端收到后,回传一个带有 SYN/ACK 标志的数据包,表示确认;
发送端再次回传一个带有 ACK 标志的数据包,表示“握手”结束。
若是传输过程出现异常,TCP 协议会启动重发机制。
IP 协议位于网络层,主要完成寻址和路由选择(routing)的任务。IP 协议利用 IP 地址来定位互联网上的计算机,再利用 ARP 协议获取中转设备的 MAC 地址,完成路由选择的任务,直到找到目标 IP 地址。
咱们以访问 xxx 为例,当咱们想去一个陌生的地方时,咱们可能只知道它的名字,好比 yy 大厦,可是咱们并不知道该如何到达,这时候咱们就须要导航的协助,帮助咱们找到 yy 大厦的具体地址,咱们就能够顺利前往了。当咱们在浏览器访问一个网站时,状况也相似。咱们在浏览器地址栏输入 www.xxx.com 后,浏览器只知道名字是 www.xxx.com,并不知道如何访问。因而,浏览器但愿 DNS 能帮助他找到名字为 www.xxx.com 的具体地址,也就是 IP 地址。DNS 通过一番查询后,告诉浏览器你要去的地方的具体地址是 192.168.0.100,因而浏览器打包请求,使用 HTTP 协议,写明请求信息。
以上的 HTTP、DNS 都属于应用层协议,数据通过封装后,浏览器将应用层的包交给下一层传输层处理。
传输层一般包含两种经常使用的协议,面向链接的TCP 协议和无链接的 UDP 协议。这里以最经常使用的 TCP 协议为例。TCP 协议一般处理进程与进程间的通讯,因此 TCP 一般带有两个端口,一个是浏览器的端口号,另外一个是目标服务器的端口号。这样,操做系统就能够给指定的端口发送包了。
接着,包会被交给网络层,IP 协议就在这一层中。网络层一般处理主机与主机间的通讯,因此 IP 协议包含浏览器所在主机的 IP 地址以及目标服务器所在主机的 IP 地址。随后操做系统将 IP 包发给链路层(MAC 层)。
在链路层会添加上 MAC 头部,而后包就能够漂洋过海了。
当服务端的链路层拿到数据后,会逐层向上发送,每到一层拿掉相应的头部,直到传输到应用层,才算真正接收到了浏览器发送过来的 HTTP 请求。
本文是《搞定 HTTP 协议》的第一篇,主要介绍了 HTTP 协议的相关历史、概念、与 HTTP 相关的协议、网络分层模型等,以帮助你们对 HTTP 造成一个整体上的直观概念。下一篇,我会介绍 HTTP 协议的整体结构,敬请期待。
最后,文章会首先发布在个人 Github ,以及公众号上,欢迎关注。
[1] RFC7230
[2] 《图解 HTTP》
[3] 极客时间 - 《透视 HTTP 协议》
[4] 极客时间 - 《趣谈网络协议》
[5] 极客时间 - 《Web 协议详解与抓包实战》