Http的发展史和各个版本之间的差异

338 阅读11分钟

前言

1991年发生了许多大事,冷战之后最大规模战争海湾战争爆发;欧共体发行了一系列条约欧盟成立;红旗落地——苏联解体。而在科技界,另一件大事也同样对今后的世界产生了不亚于苏联解体的影响。那就是1991年8月6日,世界上的第一个网站 info.cern.ch/ 正式上线,世界上的第一个网页 

http://info.cern.ch/hypertext/WWW/TheProject.html 

向世人宣告了互联网的诞生。而今你依然可以点开它,看到它,看到30年前的互联网宣言。

http0.9

互联网建立在TCP/IP协议基础上,最初由四个部分组成,包括:超文本标记语言html超文本传输协议http网络浏览器网络服务器。而诞生初的http协议像是一个借书的流程,只有简单的get方法,并且只能传输文本内容,协议格式如下

GET /index.html

它只有一行指令,因此也叫它单行协议。并且返回的内容也极其简单

<html>这是返回内容</html>

互联网的发展

再之后,互联网呈指数级的爆发,在1991年到1995年之间,浏览器和服务器不断的基于现实需求对http协议内容进行扩展尝试(期间还爆发了网景公司和微软的浏览器大战),并最终在96年发布了http1.0协议

http1.0

1.0版本就像暴富的大胖子一般,这个版本之后,任何格式的文件都可以发送,这使得互联网不仅仅可以用来传输文字,还可以传输图像、音频、视频等二进制文件,这为互联网的兴起奠定了基础。1.0相较于0.9,它主要发生了以下变化

  • 除了GET外,请求方法新增了增加了请求方式POST和HEAD
  • 请求和返回信息发生了改变,在通信中指定了 HTTP 协议版本号,增加了头信息,包含一些元信息 (比如: 状态码、权限、缓存、内容编码)
  • 除了文本内容,图片音频都能传输(content-type字段使用MIME type)

下面是请求和返回的实例

GET /index.html HTTP/1.0// 请求头
User-Agent: NCSA_Mosaic/2.0 (Windows 3.1)

返回的内容

HTTP/1.0 200 OK
Date: Tue, 18 Nov 1994 09:11:39 
GMTServer: CERN/3.0 libwww/2.17
Content-Type: text/html// 
空行
<HTML>     这是数据内容</HTML>

存在的问题

但是1.0版本的工作方式是每次TCP连接只能发送一个请求,当服务器响应后就会关闭这次连接,下一个请求需要再次建立TCP连接,就是不支持 keep-alive。 

TCP连接的建立成本很高,因为需要客户端和服务器三次握手,并且开始时发送速率较慢(slow start)。所以,HTTP 1.0版本的性能比较差。随着网页加载的外部资源越来越多,这个问题就愈发突出了。为了解决这个问题,有些浏览器在请求时,用了一个非标准的Connection字段。

http1.1

1.1版最大变化,就是引入了持久连接(persistent connection),即TCP连接默认不关闭,可以被多个请求复用,不用声明Connection: keep-alive。持久连接在客户端和服务器发现对方一段时间没有活动,就可以主动关闭。不过,规范的做法是,客户端在最后一个请求时,发送Connection: close,明确要求服务器关闭TCP连接。

Connection: close

目前,对于同一个域名,大多数浏览器允许同时建立6个持久连接。降低了延迟同时提高了带宽的利用率。

除此之外,还加入了**管道机制,**在同一个TCP连接里,允许多个请求同时发送,增加了并发性,进一步改善了HTTP协议的效率;举例来说,客户端需要请求两个资源。以前的做法是,在同一个TCP连接里面,先发送A请求,然后等待服务器做出回应,收到后再发出B请求。管道机制则是允许浏览器同时发出A请求和B请求,但是服务器还是按照顺序,先回应A请求,完成后再回应B请求。

相应的,现在一个TCP连接现在可以传送多个回应,势必就要有一种机制,区分数据包是属于哪一个回应的。这就是**Content-length**字段的作用,声明本次回应的数据长度。告诉浏览器,本次回应的长度是多少个字节,后面的字节就属于下一个回应了。

分块传输编码,使用Content-Length字段的前提条件是,服务器发送回应之前,必须知道回应的数据长度。对于一些很耗时的动态操作来说,这意味着,服务器要等到所有操作完成,才能发送数据,显然这样的效率不高。更好的处理方法是,产生一块数据,就发送一块,采用"流模式"(stream)取代"缓存模式"(buffer)。因此,1.1版规定可以不使用Content-Length字段,而使用"分块传输编码"(chunked transfer encoding)。只要请求或回应的头信息有Transfer-Encoding字段,就表明回应将由数量未定的数据块组成。

客户端请求的头信息新增了**Host**字段,用来指定服务器的域名。在HTTP1.0中认为每台服务器都绑定一个唯一的IP地址,因此,请求消息中的URL并没有传递主机名(hostname)。但随着虚拟主机技术的发展,在一台物理服务器上可以存在多个虚拟主机(Multi-homed Web Servers),并且它们共享一个IP地址。有了**Host**字段,就可以将请求发往同一台服务器上的不同网站,为虚拟主机的兴起打下了基础。(实现了在一台WEB服务器上可以在同一个IP地址和端口号上使用不同的主机名来创建多个虚拟WEB站点。也即是说,web server上的多个虚拟站点可以共享同一个ip和端口。)且请求消息中如果没有Host头域会报告一个错误(400 Bad Request)。

新增了请求方式PUT、PATCH、OPTIONS、DELETE等

HTTP/1.1支持只发送header信息,并且加入了一个新的状态码100(Continue)。客户端事先发送一个只带头域的请求,如果服务器因为权限拒绝了请求,就回送响应码401(Unauthorized);如果服务器接收此请求就回送响应码100,客户端就可以继续发送带实体的完整请求了。100 (Continue) 状态代码的使用,允许客户端在发request消息body之前先用request header试探一下server,看server要不要接收request body,再决定要不要发request body。

总结一下http1.1版主要特点如下

  • 引入了持久连接,降低了延迟同时提高了带宽的利用率

  • 加入了****管道机制,进一步改善了HTTP协议的效率

  • 新增了部分字段,**Content-length,Transfer-Encoding,**Host

  • 新增了请求方式PUT、PATCH、OPTIONS、DELETE

  • 支持只发送header信息,并且加入了一个新的状态码100,节约了带宽。

存在的问题

虽然1.1版允许复用TCP连接,但是同一个TCP连接里面,所有的数据通信是按次序进行的。服务端是按队列顺序处理请求的,服务器只有处理完一个回应,才会进行下一个回应。假如前面的请求处理时间很长,后面就会有许多请求排队等着,这样就造成了“队头阻塞”的问题;同时HTTP是无状态的连接,因此每次请求都需要添加重复的字段,降低了带宽的利用率。

多路复用带来一个新的问题是,在连接共享的基础之上有可能会导致关键请求被阻塞。SPDY允许给每个request设置优先级,这样重要的请求就会优先得到响应。比如浏览器加载首页,首页的html内容应该优先展示,之后才是各种静态资源文件,脚本文件等加载,这样可以保证用户能第一时间看到网页内容。

为了避免这个问题,只有两种方法:一是减少请求数,二是同时多开持久连接。这导致了很多的网页优化技巧,比如合并脚本和样式表、将图片嵌入CSS代码、域名分片(domain sharding)等等。如果HTTP协议设计得更好一些,这些额外的工作是可以避免的。

http2.0

HTTP/2.0版本,增加全双工模式,即不仅客户端能够同时发送多个请求,服务端也能同时处理多个请求,解决了队头堵塞的问题(HTTP2.0使用了多路复用的技术,做到同一个连接并发处理多个请求,而且不用按照顺序一一对应,并发请求的数量也比HTTP1.1大了好几个数量级)

因为 HTTP/2 的数据包是不按顺序发送的,同一个连接里面连续的数据包,可能属于不同的回应。因此,必须要对数据包做标记,指出它属于哪个回应。HTTP/2 将每个请求或回应的所有数据包,称为一个数据流(stream)。每个数据流都有一个独一无二的编号。数据包发送的时候,都必须标记数据流ID,用来区分它属于哪个数据流。另外还规定,客户端发出的数据流,ID一律为奇数,服务器发出的,ID为偶数。数据流发送到一半的时候,客户端和服务器都可以发送信号(RST_STREAM帧),取消这个数据流。1.1版取消数据流的唯一方法,就是关闭TCP连接。这就是说,HTTP/2 可以取消某一次请求,同时保证TCP连接还打开着,可以被其他请求使用。客户端还可以指定数据流的优先级。优先级越高,服务器就会越早回应。

另外也增加服务器推送的功能,即不经请求服务端主动向客户端发送数据。

当前主流的协议版本还是HTTP/1.1版本。1.1 版的头信息肯定是文本(ASCII编码),数据体可以是文本,也可以是二进制。HTTP/2 则是一个彻底的二进制协议,头信息和数据体都是二进制,并且统称为"帧"(frame):头信息帧和数据帧。二进制协议的一个好处是,可以定义额外的帧。HTTP/2 定义了近十种帧,为将来的高级应用打好了基础。如果使用文本实现这种功能,解析数据将会变得非常麻烦,二进制解析则方便得多。

HTTP请求和响应中,状态行和请求/响应头都是些信息字段,并没有真正的数据,因此在2.0版本中将所有的信息字段建立一张表,为表中的每个字段建立索引,客户端和服务端共同使用这个表,他们之间就以索引号来表示信息字段,这样就避免了1.0旧版本的重复繁琐的字段,并以压缩的方式传输,提高利用率。

http2.0的特点:

  • 增加**全双工模式,**客户端和服务端都能能够同时发送请求

  • 添加**数据编号,可以取消某一次请求,同时保证TCP连接还打开着,**客户端还可以指定数据流的优先级

  • 增加**服务器推送,**服务端主动向客户端发送数据

  • 彻底的二进制协议,头信息和数据体都是二进制,将所有的信息字段建立一张表,头信息复用

https

文章的最后多提一嘴https。98年后搜狐新浪等门户网站一时独领风骚,99年腾讯上场,2000年百度进击,2003年淘宝上线,由此开启了十几年的PC互联网时代。2009年,中国进入3G时代,2010年苹果公司发布iphone4,由此又开始了移动互联网时代直到5Giphone12发布的今天。而我们的HTTP协议也经历了从无到有,两次改版,达到了比较友好的状态,目前还有两个问题,一个是安全问题,另一个是速度问题。

而我们要说的https就是安全问题,它是以安全为目标的 HTTP 通道,在HTTP的基础上通过传输加密和身份认证保证了传输过程的安全性。由 HTTP 加上 TLS/SSL 协议构建的可进行加密传输、身份认证的网络协议,主要通过数字证书加密算法、非对称密钥等技术完成互联网数据传输加密,实现互联网传输安全保护。具体的大家可以网上找到,文章就不做过多介绍。

如果对大家有帮助,大家帮忙点个星,如果哪里有错误欢迎大家指出,一起学习~