http(超文本传输协议),从开始做前端开发,就一直接触http,但是突然发现自己对http的了解基本上就是知道有这么个东西,然后就没有然后了。毕竟日常工作中能用到http的大部分情况就是调用一下后台的接口,获取到后台返回的数据,然后将数据应用到页面里面,在多一点,也就是对axios做一个简单的封装,我对axios的了解都不多,更何况是http呢。
但是人嘛,总是有一些好奇心的,遵循着好奇心的驱使,我尽我可能得查询了一些http的资料,这里就简单的讲一讲我理解中的http,鉴于理解粗浅,漏洞百出,希望有懂得人可以再评论区纠正一下,给我一个学习的机会。
http协议的发展
http协议是基于tcp/ip协议的应用层协议,知乎有一个简单概括我感觉挺好的
http是一个在计算机世界里专门在两点之间传输文字、图片、音频、视频等超文本数据的约定和规范。
作为一个数据传输协议,从建立之初,http就是一个无状态的请求,所以我们通过各种方式将数据加到http的请求中,以保证后台了解到用户端的状态。当然,这部分方法很多,这里就不细说了,先说http协议本身吧。
http 0.9
http的最早版本是1991年的http0.9版本,该版本极其简单,只有一个get请求。
get/ index.html
这个请求表示向服务器请求index.html文件。当然鉴于过于古老,也没什么参考价值,这里就不多缀叙。
http1.0
1996年5月,HTTP/1.0 版本发布,内容大大增加。
首先,任何格式的内容都可以发送。这使得互联网不仅可以传输文字,还能传输图像、视频、二进制文件。这为互联网的大发展奠定了基础。
其次,除了GET命令,还引入了POST命令和HEAD命令,丰富了浏览器与服务器的互动手段。
再次,HTTP请求和回应的格式也变了。除了数据部分,每次通信都必须包括头信息(HTTP header),用来描述一些元数据。
其他的新增功能还包括状态码(status code)、多字符集支持、多部分发送(multi-part type)、权限(authorization)、缓存(cache)、内容编码(content encoding)等。
这时候就已经很像现在我们所用的http请求了,有请求头文件,常用的GET请求和POST请求。
http1.0的请求模式是请求开始是先进行tcp/ip连接,每次连接之后只能发送一个请求,在响应后断开tcp/ip连接。由于tcp/ip连接的新建成本较高,导致在需要请求大量外部资源时页面响应速度受限于http请求速度。
http1.0时期并不是完全没有想过解决方法,当时添加了一个非标准字段:connection。
Connection: keep-alive
这个字段可以要求服务器不要关闭tcp连接,以便于其他请求继续使用这个tcp连接。但是鉴于这是一个非标准字段,所以实现方式并不统一,无法作为一个彻底的解决方案。
http1.1
1997年1月,HTTP/1.1 版本发布,只比 1.0 版本晚了半年。它进一步完善了 HTTP 协议,一直到了现在,还有很多网站使用http1.1。
http1.1引入了持续连接,就是http1.0版本中需要用connection才能做到的tcp连接多次使用。在http1.1中,tcp连接时默认不关闭的,当客户端或者服务器发现对方一段时间没有活动,才会主动关闭tcp连接。不过这样不太好,规范的方法是当发送最后一个http请求是,发送connection: close,明确要求关闭tcp连接。
http1.1还引入了管道机制(pipelining),既在一个tcp连接中,客户端可以同时发送多个请求,而不是像http1.0中一个请求响应之后才能发送下一个请求,这样有效提高了客户端的http请求效率。
当然,这种方法需要一个字段content-length,用来告诉浏览器这些数据是属于哪个请求的。
Content-Length: 1024
这段代码是告诉浏览器这个请求返回的数据长度是1024,1024之后的数据是下一个请求的。这也意味着虽然管道机制让客户端同时发送多个请求,但是这些请求还是有顺序的,而且一定是按照请求的顺序依次返回的。
这也暴露了一个问题,如果说http1.0是因为客户端的请求慢的话http1.1就是因为服务器的响应慢了,毕竟如果第一个请求耗时过长的话后面的请求只能等第一个请求响应之后才能继续响应,这也算是http1.1的一个缺点,不过比起http1.0来看,这不算什么问题了。
http1.1中还新增了几个方法,像是PUT, OPTION之类的。
http2
本来中间google公司使用过spdy协议对http1.1进行优化,不过鉴于主要特性都在http2中得到继承,就不细说,直接说http2了。
http1.1和http2最大的区别是http1.1是半双工,http2是全双工。http1.1是先统一请求,然后顺序响应,返回数据。http2是统一请求,然后响应,没有顺序。这里涉及到http2的一个大改动,http1.1的头信息是文本,请求本身可以是文本,也可以是二进制。而http2则是请求头和请求本身都是二进制,具体原因我不太清楚,但是二进制传输可以保障数据传输过程中数据流的双向传输,以及服务器不在必须按照请求顺序响应了,这样就将http1.1中服务器的响应问题解决了。
而且http2还引入了压缩机制,将重复信息导入表,通过索引号进行查询。还可以由服务器主动向客户端发送数据。
以上是我对http的一些理解,当然,如果只是这些的话我还不如直接讲阮一峰大佬的文章复制过来更省事,下面我还有一些个人理解。这部分与其说理解,不如说是一些疑惑,希望看到的大佬可以帮助解答一下。
个人理解
以chrome浏览器为例,早期的http1.0暂不考虑,http1.1最多可以进行六条tcp连接,所以如果在请求中某个请求就是特别慢的话通过改变接口的方式,单独使用一个tcp连接,可以保证页面的响应速度,当然http2不需要考虑这个问题。
我没在网上找到http2在chrome浏览器上能保持多少条tcp连接,所以也没办法去描述这个了。
那么我不太理解的地方来,在日常的业务逻辑中,http请求并不是同时发送的,以vue为例,代码运行,生命周期等等的不同导致即使是同一个ip的接口也会有先后顺序,那么这个时候是新建tcp连接,还是使用当前已有的tcp连接。如果使用已有的tcp连接,鉴于http1.1是半双工的,那么是要等请求全部响应之后再发送新的请求还是直接在http1.1没有返回数据的时候发送呢,如果是后者我还会有其他的问题,不过暂时先不继续问了。http2是全双工的,可以做到直接请求,但是如果tcp连接中的数据流过大又会怎么样呢?毕竟之后开始获取之后才知道数据流的大小,还是说如果数据流过大,则由服务器通知客户端新建一条tcp连接去专门应对大的数据流么?
好吧,问题大概就是这些了,其实这篇文章更多是为了提出这些问题,希望有大佬能帮助解答一些我的疑惑。先感谢了。