一、定义
http协议:超文本传输协议(通信协议),用于从服务器传输超文本到本地浏览,建立再TCP/IP协议基础上
三个特点:
1、无连接
是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间
2、无状态
是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快
3、灵活
允许传输任意类型的数据对象。传输的类型由Content-Type(Content-Type是HTTP包中用来表示内容类型的标识)加以标记
HTTP/0.9版本
特点:结构简单,仅有GET请求,纯文本格式
例如GET /index.html
表示:TCP建立连接后,客户端向服务端请求index.html页面,协议规定,服务端只能返字符串,返回后即关闭TCP链接,如果请求的页面不存在,也不反悔任何错误码,这也是无状态的一个体现
HTTP/1.0版本
相比较上一个版本增加了如下主要内容:
- 增加了post请求,丰富了浏览器与客户端的互动手段
- 传输数据不限于文本,可以是图片、视频、二进制文件等内容
- 增加了协议版本号
- 增加的响应状态码
- 引入了HTTP HEADER(头部)概念,让HTTP处理请求更加灵活
GET /HTTP/1.0
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5)
Accept: */*
HTTP/1.0 200 OK
Content-Type: text/plain
Content-Length: 137582
Expires: Thu, 05 Dec 1997 16:00:00 GMT
Last-Modified: Wed, 5 August 1996 15:55:28 GMT
Server: Apache 0.84
<html>
<body>Hello World</body>
</html>
其中content-type是体现灵活的字段,我们常见的value值包括:text/html, text/css, image/png, application/javascript, application/x-www-form-urlencoded form, Multipart/form-data,以上数据统称为MIME类型。
1.0的缺点:
连接无法复用:每个TCP连接只能发送一个请求。发送数据完毕,连接就关闭,如果还要请求其他资源,就必须再新建一个连接。
为了解决这个问题,有些浏览器在请求时,用了一个非标准的Connection字段:Connection: keep-alive,表示TCP可以复用,直到主动关闭链接。
上面是又没有keep-alive的区别,但是这不是标准字段,不同实现的行为可能不一致,因此不是根本的解决办法,并且TCP的新建成本很高,因为每次链接服务端和客户端都需要经过三次握手,并且开始时发送的速率较慢。
HTTP/1.1版本
也就是目前位置用的最多的一个版本,相比较1.0版本增加了:
- 持久链接,默认TCP不关闭,可以被多个请求复用,不用申明connection:keep-alive字段
- 新增了PUT、PATCH、OPTIONS、DELETE请求方法,也新增了许多状态码
- 强制HOST头:HTTP1.0中认为每台服务器都绑定一个唯一的IP地址,因此,请求消息中的URL并没有传递主机名(hostname)。但随着虚拟主机技术的发展,在一台物理服务器上可以存在多个虚拟主机(Multi-homed Web Servers),并且它们共享一个IP地址。HTTP1.1的请求消息和响应消息都应支持Host头域,且请求消息中如果没有Host头域会报告一个错误(400 Bad Request)。有了Host字段,就可以将请求发往同一台服务器上的不同网站,为虚拟主机的兴起打下了基础
- 缓存处理:HTTP/1.0 使用 Pragma:no-cache + Last-Modified/If-Modified-Since + Expire来作为缓存判断的标准;HTTP/1.1 引入了更多的缓存控制策略:Cache-Control、Etag/If-None-Match
管道机制(pipelining):即在同一个TCP链接里面,客户端可以同事发送多个请求。从而进一步改善HTTP协议的效率问题
例如:客户端需要请求两个资源。以前的做法是,在同一个TCP连接里面,先发送A请求,然后等待服务器做出回应,收到后再发出B请求。管道机制则是允许浏览器同时发出A请求和B请求,但是服务器还是按照顺序,先回应A请求,完成后再回应B请求,通过下图可以很清晰的看出区别
1.1缺点:
虽然1.1版允许复用TCP连接,但是同一个TCP连接里面,所有的数据通信是按次序进行的。服务器只有处理完一个回应,才会进行下一个回应。要是前面的回应特别慢,后面就会有许多请求排队等着。这称为“队头堵塞"(Head-of-line blocking)
解决方案:
1、减少请求数量(雪碧图)
2、多开持久链接,如下图中并行的请求,就是多开了几个TCP链接,但是浏览器也有规定,同一域名下TCP开启的个数时有限,一般不超过10个,这也是SEO中,将资源CDN的原因。
个人见解:1.1版本中增加了许多头部的标识,使得请求更加的灵活,例如类型、缓存等等!利用好了能大幅提升请求效率,也可以当作优化的重点去攻克!但是也有太多的字段需要去学习,有利有弊吧!接下来就是重点HTTP/2
HTTP/2版本
为什么是2而不是2.0,因为标准委员会不准备发布子版本,下一个版本将是HTTP/3
1、二进制传输:在HTTP1.x中,我们是通过文本的方式传输数据。基于文本的方式传输数据存在很多缺陷,文本的表现形式有多样性,因此要做到健壮性考虑的场景必然有很多,但是二进制则不同,只有0和1的组合,因此选择了二进制传输,实现方便且健壮。为了保证HTTP不受影响,那就需要在应用层(HTTP2.0)和传输层(TCP or UDP)之间增加一个二进制分帧层。在二进制分帧层上,HTTP2.0会将所有传输的信息分为更小的消息和帧,并采用二进制格式编码,其中HTTP1.x的首部信息会被封装到Headers frame,而Request Body则封装到Data frame。
2、头部压缩(Header Compression):专门为头部压缩设计了Hpack算法,简单来说就是客户端和服务端共同维护一份相同的静态表和动态表,在编码时直接用表的index代替,可以大幅降低头部大小
3、服务端推送(server push):允许服务器未经请求,主要向客户端发送资源。
客户端请求一个网页,这个网页里面包含很多静态资源。正常情况下,客户端必须收到网页后,解析HTML源码,发现有静态资源,再发出静态资源请求。其实,服务器可以预期到客户端请求网页后,很可能会再请求静态资源,所以就主动把这些静态资源随着网页一起发给客户端了
4、多路复用:也是最重要的一项,起因是1.X版本中的“队头阻塞”,这里面有三个比较重要的概念
- 消息:逻辑上的http消息,比如一系列Data frame 和 一个Header frame 组成的请求消息
- 帧(frame):最小的数据单位
- 流(stream):多个帧组成数据流,每个帧会标识出该帧属于哪个流,通俗讲流是连接中的一个虚拟信道,可以承载双向消息传输,每一个流都有唯一的标识,为了防止两个流ID冲突,客户端发起的流具有奇数ID,服务端发起的流具有偶数ID,所有的HTTP2通信都在一个TCP链接上完成,这个连接可以承载任意数量的双向数据流Stream。 相应地, 每个数据流以 消息的形式发送, 而消息由一 或多个帧组成, 这些帧可以乱序发送, 然后根据每个帧首部的流标识符重新组装。
举个例子,每个请求是一个数据流,数据流以消息的方式发送,而消息又分为多个帧,帧头部记录着stream id用来标识所属的数据流,不同属的帧可以在连接中随机混杂在一起。接收方可以根据stream id将帧再归属到各自不同的请求当中去。
另外,多路复用(连接共享)可能会导致关键请求被阻塞。HTTP2里每个数据流都可以设置优先级和依赖,优先级高的数据流会被服务器优先处理和返回给客户端,数据流还可以依赖其他的子数据流。
可见,HTTP2实现了真正的并行传输,它能够在一个TCP上进行任意数量HTTP请求。而这个强大的功能则是基于“二进制分帧”的特性。
宏观上看,基于二进制分帧层,htp2可以在共享TCP链接的基础上,同时发送请求和响应,HTTP消息被分解为独立的帧,交错发出,最后在另一端根据ID和首部将它们重新组合起来。
以上就是HTTP2主要的特点,接下来会是HTTP3的特点,未完待续。。。。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。