目录
6.HTTP1.0、 HTTP1.1、HTTP2.0、HTTP3.0对比
1.HTTP特点
HTTP:超文本传输协议
- 无状态(不保存状态)
- HTTP本身不对请求和响应之间的通信状态进行保存(也就是说,HTTP协议对于发送的请求、响应都不做持久化处理)
- 比如:用户登录一家购物网站,即使他跳转到该网站的其他页面后,也需要能继续保持登录状态。针对这个示例,网站为了能够掌握是谁送出的请求,需要保存用户的状态(否则的话每次都要重新登录) ==> 为了实现保持状态的功能,引入了cookie技术,cookie可以管理状态
- cookie技术
- 过程
- 第一次客户端请求,此时没有cookie
- 客户端向服务端发送请求,此时,
- 服务端生成cookie
- 服务端将保存cookie以及cookie是谁发送而来的
- cookie与响应体一起返回给客户端
- 客户端将收到的cookie保存起来
- 第二次客户端请求,此时,
- 客户端发送请求时,除了请求体,还携带cookie
- 服务端收到了请求后,拿到cookie后,就可以识别出该cookie对应的机器
- 详细过程:cookie、session
- 客户端把(用户ID,密码)等登录信息放入报文的实体部分,通常以POST方法把请求发送给服务端
- 服务端会使用 [ key=(用户ID,密码)等登录信息 ] 生成识别用户的SessionID。将其保存在服务端。之后,服务端返回响应给客户端,会在响应首部字段Set-Cookie内写入SessionID
- 客户端接收到SessionID后,会将其作为Cookie保存在本地。
- 下次客户端向服务器发送请求时,浏览器会自动发送Cookie,所以SessionID也会随之发送到服务器;服务器可通过验证接收到的SessionID识别用户及其认证状态
- 第一次客户端请求,此时没有cookie
- 过程
- HTTP本身不对请求和响应之间的通信状态进行保存(也就是说,HTTP协议对于发送的请求、响应都不做持久化处理)
- 非持久化链接
- HTTP初始版本,每进行一次通信就要断开一次TCP连接
- 以当年的通信情况来说,因为都是容量很小的文本文件,所以即使这样也没有多大问题。可是,随着时间的推移,文档中包含大量的图片文件,这样就性能低下了
- 持久连接:HTTP keep-alive
- 只要在任意一端没有明确的提出断开链接,则保持TCP连接状态
- 持久连接的好处
- 减少了TCP连接的建立和断开造成的额外开销,减轻了服务器的负载
- 减少了开销的那部分时间,使得HTTP请求和响应能够更早的结束
- HTTP初始版本,每进行一次通信就要断开一次TCP连接
- 管线化 Pipeline
- 持久连接使得多数请求以管线化方式发送成为可能
- 之前,发送请求后需要等待并收到响应,才能发送下一个请求,管线化技术出现后,不用等待响应也可以直接发送下一个请求,这样就能并行发送多个请求,而不需要一个接一个的等待响应了
- 例子:当请求一个包含 10 张图片的 HTMLWeb 页面,与挨个连接相比,用持久连接可以让请求更快结束。而管线化技术则比持久连接还要快。请求数越多,时间差就越明显
- 特点:即可在同一个 TCP 连接里面,客户端可以发起多个请求,只要第一个请求发出去了,不必等其回来,就可以发第二个请求出去,可以减少整体的响应时间
- 弊端:服务器必须按照接收请求的顺序发送对这些管道化请求的响应
- 注意,是按照服务端收到的请求顺序响应,并不管哪个请求是先发送的
- 假设:
- 客户端先发送 A 请求,后发送 B 请求
- 如果服务端先收到 B 请求,就先响应 B 请求,然后再响应 A 请求
- 但是假设处理 B 请求的时候,耗时比较长,那么请求 A 的响应就会被阻塞,这称为「队头堵塞」
- 总结:HTTP/1.1 管道解决了请求的队头阻塞,但是没有解决响应的队头阻塞
- 持久连接使得多数请求以管线化方式发送成为可能
2.首部字段Header
- 说明:首部字段,起到传递额外重要信息的作用
- HTTP首部字段结构:首部字段名称: 字段值,如,Content-Type: text/html
重要的首部字段
connection
2.1. 通用首部字段
请求报文和响应报文两方都会使用的首部。
Connection
- 控制不在转发给代理的首部字段
- Connection: Upgrade,表示首部字段转发到代理服务器后,删除connection指定的字段Upgrade后,再转发到源服务器
- 管理持久连接
- Connection: keep-alive 保持持久化连接
- Connection: close 发送明确的断开链接
Date
- 表示创建HTTP报文的日期和时间
Transfer-Encoding
- 规定了传输报文主体时采用的编码方式
Upgrade
- 用于检测HTTP协议以及其他协议可使用更高版本进行通信,其参数值可以用来指定一个完全不同的通信协议。
2.2. 请求首部字段
客户端向服务端发送请求报文时使用的首部。补充了请求附加内容、客户端信息、响应内容相关优先级等信息。
Host:客户端发送请求时,用来指定服务器的域名
虚拟主机运行在同一个IP上,因此使用首部字段Host加以区分
首部字段Host(Host: www.hackr.jp)会告知服务器,请求的资源所处的互联网主机名和端口号。
Anthorization
用来告知服务器,用户代理的认证信息。(与401错误码配合使用)
Authorization: Basic dWVub3NlbjpwYXNzd29yZA==
User-Agent
将创建请求的浏览器和用户代理名称等信息传达给服务器。
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:13.0) Gecko
Referer
首部字段Rederer会告知服务器请求的原始资源的URI
Range
对于只需要获取部分资源的范围请求,包括首部字段Range即可告知服务器资源的指定范围。
备注:接收到附带Range首部字段请求的服务器,会在
- 处理请求之后返回状态码为206Partial Content的响应
- 无法处理该范围请求时,则会返回状态码200 OK响应全部资源
Range: bytes=5001-10000,表示请求获取从第5001到10000字节的资源
Max-Forwards
通过Trace方法或Options方法,发送包含首部字段Max-Forwards的请求时,该字段指定可以经过服务器最大数目。
Accept
通知服务器,用户代理能够处理的媒体类型以及媒体类型的相对优先级(可使用type/subtype这种形式,一次指定多种媒体类型)
媒体类型
- 文本文件
- 图片文件
- 视频文件
- 应用程序使用的二进制文件
Accept-Charset
通知服务器用户代理支持的字符集以及字符集的相对优先顺序
Accept-Encoding
告知服务器用户代理支持的内容编码以及内容编码的优先级顺序。可一次性指定多种内容编码。
编码方式:gzip、compress、deflate、identity
Accept-Language
告知服务器用户代理能够处理的自然语言集合以及自然语言集合的相对优先级。可一次指定多种自然语言集。
条件请求 If-XXX
服务器接收到条件请求后,只有判断指定条件为真,才会执行请求
If-Match:告知服务器匹配资源所用的实体标记值Etag(服务器对比If-Match的字段值和资源Etag,当且仅当二者一致时,才会执行请求。繁殖,返回412Precondition Failed的响应)
If-Modified-Since:如果在If-Modified-Since指定的日期时间后,资源发生了更新,服务器才会接收请求
- 在If-Modified-Since指定的日期时间后,
- 资源发生了更新,该请求能被处理
- 资源未发生更新,返回304 Not Modified的响应
If-Range:它告知服务器若指定的If-Range字段值(Etag值或时间)和请求资源的Etag值或时间相一致时,则作为范围请求处理。反之,则返回全体资源。
2.3. 响应首部字段
服务端向客户端返回响应报文时使用的首部。补充了响应的附加内容,也会要求客户端附加额外的内容信息。
Accept-Ranges
用来告知客户端,服务器是否能处理范围请求(分为两种结果)
- 可处理范围请求:bytes
- 不可处理范围请求:none
Etag
首部字段Etag能告知客户端实体的唯一标识。服务端为每份资源分配一个Etag。
Location
- Location可以将响应接收方引导至每个与请求URI位置不同的资源
- Location与返回码3XX配合:提供重定向的URI
Retry-After
告知客户端,在多久后可以发起重试请求。主要配合503 Service Unavailable响应
Age
Age能告诉客户端,服务器在多久前创建了响应。
2.4. 实体首部字段
针对请求报文和响应报文的实体部分使用的首部。补充了资源内容更新时间等与实体有关的信息。
Allow:通知客户端,能够支持的HTTP方法method
Content-Encoding:告知客户端,服务器对实体的主体部分选择使用的编码方式
Content-Encoding: gzip
Content-Language:告知客户端,服务器对实体的主体部分使用的语言(中文或英文等)
Content-Language: zh-CN
Content-Length:表示实体主体部分的大小(字节)
Content-Length: 15000
Content-Location:首部字段Content-Location给出与报文主体部分相对应的URI。
- 和首部字段Location不同,Content-Location表示的是报文主体返回资源对应的URI。
- 比如,对于使用首部字段 Accept-Language 的服务器驱动型请求,当返回的页面内容与实际请求的对象不同时,首部字段 Content-Location 内会写明 URI。(访问 http://www.hackr.jp/ 返回的对象却是 http://www.hackr.jp/index-ja.html 等类似情况)
Content-Location: http://www.hackr.jp/index-ja.html
Content-MD5:在于检查报文主体在传输过程中是否保持完整,以及确认传输到达
Content-MD5: OGFkZDUwNGVhNGY3N2MxMDIwZmQ4NTBmY2IyTY==
Content-Range:针对范围请求,返回响应时使用的首部字段Content-Range,能告知客户端作为响应返回的实体的哪个部分符合范围请求。
Content-Range: bytes 5001-10000/10000
Content-Type:说明了实体主体内对象的媒体类型。
Content-Type: text/html; charset=UTF-8
Expires:资源失效的日期
Expires: Wed, 04 Jul 2012 08:26:05 GMT
Last-Modified:资源最近一次修改的时间
Last-Modified: Wed, 23 May 2012 09:59:55 GMT
2.5.为Cookie服务的首部字段
Cookie
- 请求首部字段
- 功能:告诉服务器,携带的Cookie
Set-Cookie
- 响应首部字段
-
Set-Cookie: status=enable; expires=Tue, 05 Jul 2011 07:26:31
-
当服务器准备开始管理客户端状态时,会事先告知各种信息
-
Set-Cookie字段的属性
-
name=value:赋予Cookie的名称和值(必需项)
-
expire=Date:cookie的有效期(若不指定,则默认为浏览器关闭前为止)
-
path=PATH:将服务器上的文件目录作为cookie的适用对象
-
domain=域名:作为cookie适用对象的域名
-
Secure:仅在HTTPS安全通信时才会发送cookie
-
HttpOnly:加以限制,仅cookie不能被JavaScript脚本访问
-
3.报文
3.1.请求报文的构成
请求报文:[请求方法、请求URI、HTTP协议版本]、[可选的请求首部]、[内容实体]
请求行:[method] [URI] [HTTP版本]
- GET 请求方法method
- /index.html 请求URI:请求访问的资源对象
- URI 统一资源定位符 Uniform Resource Locator:使用URI定位到互联网上的资源
- Uniform:规定统一的格式
- Resource:可标识的任何东西
- Identifier:标识可标识的对象
- URI 统一资源定位符 Uniform Resource Locator:使用URI定位到互联网上的资源
- HTTP/1.1 HTTP的版本号
请求首部
空行
内容实体
3.2.响应报文的构成
响应报文:[HTTP协议版本、状态码、原因短语]、[可选的响应首部]、[内容实体]
响应行: HTTP/1.1 HTTP的版本号、200 状态码、OK 原因短语
响应首部
空行
资源实体的主题(entity body)
3.3.HTTP方法(method)
GET:获取响应的主体内容
POST:传输实体主体
PUT:传输文件(就向FTP协议的文件上传一样,要求在请求报文的主体中包含文件内容,然后保存到请求URI指定的位置)
HEAD:获得报文首部(和GET一样,只是不返回报文的主体部分,用于确认URI的有效性、资源更新的日期时间等)
DELETE:删除文件(与PUT方法相反),按照请求URI删除指定资源
OPTIONS:询问支持的方法
TRACE:追踪路径(让web服务器端将之前的请求通信环回给客户端的方法)
1. 发送请求时,在 Max-Forwards 首部字段中填入数值,每经过一个服务器端就将该数字减 1,当数值刚好减到 0 时,就停止继续传输,最 后接收到请求的服务器端则返回状态码 200 OK的响应
2. 客户端通过 TRACE 方法可以查询发送出去的请求是怎样被加工修改 / 篡改的。这是因为,请求想要连接到源目标服务器可能会通过代理中转,TRACE 方法就是用来确认连接过程中发生的一系列操作
CONNECT:要求用隧道协议连接代理
3.3.1. GET和POST区别
①请求参数保存的位置 ②数据格式 ③数据大小限制
- GET 的语义是从服务器获取指定的资源,这个资源可以是静态的文本、页面、图片视频等。GET 请求的参数位置一般是写在 URL 中,URL 规定只能支持 ASCII,所以 GET 请求的参数只允许 ASCII 字符 ,而且浏览器会对 URL 的长度有限制(HTTP协议本身对 URL长度并没有做任何规定)
- POST 的语义是根据请求负荷(报文body)对指定的资源做出处理,具体的处理方式视资源类型而不同。POST 请求携带数据的位置一般是写在报文 body 中, body 中的数据可以是任意格式的数据,只要客户端与服务端协商好即可,而且浏览器不会对 body 大小做限制
Q2: GET和POST方法都是幂等的么?
A2:
- GET是[只读]操作,是幂等的
- POST因为是[新增or提交]数据的操作,会修改服务器上的资源,所以是不幂等的
4.状态码
HTTP状态码负责表示客户端HTTP请求的返回结果、标记服务器端的处理是否正常、通知出现的错误等工作。
状态码的类别
4.1. 2XX成功
200 OK,从客户端发来的请求在服务端被正常处理了
在响应报文内,随状态码一起返回的信息会因方法的不同而发生改变。比如,
- 使用GET方法时,对应请求资源的实体会作为响应返回
- 使用HEAD方法时,对应请求的实体首部不随报文主体作为响应返回
204 Not Content,服务端接收到的请求已经成功处理,但是在返回的响应报文中不包含实体的主体部分
比如,当从浏览器发出请求处理后,返回204响应,那么浏览器显示的页面不发生更新
206 Partial Content,表示客户端进行了范围请求,而服务端成功执行了这部分的GET请求。响应报文中包含由Content-Range指定范围的实体内容
- 应用场景:HTTP分块下载或断点续传,表示数据并不是资源的全部,而是一部分
4.2. 3XX 重定向
301 Moved Permanently 永久重定向,表示请求的资源已经被分配到了新的URI,以后就使用资源现在所指的URI。
- 说明请求的资源已经不存在了,需要改用新的URL再次访问
302 Found,临时性重定向,表示请求的资源已经被分配了新的URI,希望用户本次能使用新的URI访问。
- 表示临时重定向,说明请求的资源还在,但暂时需要用另一个 URL 来访问
补充:301和302都会在响应头里使用字段Location,指明后续跳转的URL,浏览器会自动重定向到新的URL。
303 See other,表示由于请求对应的资源存在着另一个URI,应使用GET方法定向获取请求的资源。
注解:303和302有着相同的功能,但303明确表示客户端应当采用GET方法获取资源,这点与302有区别。比如,
- 当使用POST方法访问CGI程序,其执行后的处理结果是希望客户端能以GET重定向到另一个URI上面去(可以看到,这里method方法变化了,由POST变为GET),返回303。虽然302也可以实现相同的功能,但这里使用303是最理想的。
补充:HTTP的RFC规范,不允许客户端在重定向时改变请求的方法mentod
① 当 301、302、303 响应状态码返回时,几乎所有的浏览器都会把 POST 改成 GET,并删除请求报文内的主体,之后请求会自动再次发送
② 301 、 302 标准是禁止将 POST 方法改变成 GET 方法的,但实际使用时大家都会这么做
307 Temporary Redirect,临时重定向,该状态码和302有着相同的含义。
为了解决上面的问题:尽管RFC标准禁止POST变换成GET,但是实际使用时大家并不遵守。引出了307。==> 307会遵照浏览器标准,不会从POST变成GET。但是,对于处理响应的行为,每种浏览器可能出现不同的情况。
304 Not Modified,表示客户端发送附带条件的请求时,服务端允许请求访问资源,但未满足条件的情况。
- 不具有跳转的含义,表示资源未修改,重定向已存在的缓冲文件,也称缓存重定向,也就是告诉客户端可以继续使用缓存资源,用于缓存控制
- 304 虽然被划分在 3XX 类别中,但是和重定向没有关系
4.3. 4XX 客户端错误
400 Bad Request,表示客户端请求的报文有错误,但只是个笼统的错误。(服务端无法理解客户端发送的请求)
- 请求报文有错误
- 当错误发生时,需要修改请求的内容再次发送请求
401 Unauthorized,表示发送的请求需要有通过HTTP认证的认证信息。另外,若之前已进行过一次请求,则表示用户认证失败。
- 返回含有 401 的响应必须包含一个适用于被请求资源的 WWW-Authenticate 首部用以质询(challenge)用户信息。当浏览器初次接收到 401 响应,会弹出认证用的对话窗口。
403 Forbidden 表示对请求资源的访问被服务器拒绝了
- 表示服务器禁止访问资源,并不是客户端的请求出错
服务器没有必要给出拒绝的详细理由,但如果想做说明的话,可以在实体的主体部分对原因进行描述,这样就能让用户看到了。
未获得文件系统的访问授权,访问权限出现某些问题(从未授权的发送源IP地址试图访问)等列举的情况都可能是发生403的原因。
404 Not Found
- 表示请求的资源在服务器上不存在或未找到,所以无法提供给客户端
使用场景
- 表示服务器上无法找到请求的资源
- 在服务器端拒绝请求且不想说明理由时使用
4.4. 5XX 服务端错误
5XX类状态码表示客户端请求报文正确,但是服务器处理时内部发生了错误,属于服务器端的错误码。
500 Internal Server Error 表示服务端在执行请求时发生了错误(可能是web应用存在的bug或某些临时的故障)
- 是个笼统通用的错误码,服务器发生了什么错误,我们并不知道
501 Not Implemented 表示客户端请求的功能,服务端还不支持,类似”即将开业,敬请期待“的意思
502 Bad Gateway 通常是服务器作为网关或代理时返回的错误码,表示服务器自身工作正常,访问后端服务器发生了错误
503 Service Unavailable 服务器忙碌,暂时无法提供服务,类似”网络服务正忙,请稍后重试“
- 如果能实现得知解除以上状况需要的时间,最好写入RetryAfter首部字段再返回给客户端
- 客户端就可以指定过K时间后重试
5.HTTPS
5.1.什么是HTTPS
HTTP的缺点
- 明文传输(内容被窃听)
- 无身份验证(通信方可能被伪装)
- 无法证明报文传输的正确性(报文可能会被篡改)
HTTPS
通过和SSL(secure Socket Layer,安全套接层)或TLS(Transport Layer Security,安全层传输协议)的组合使用,建立安全通信线路后,加密HTTP的通信内容。
HTTPS = HTTP + 加密 + 身份认证 + 完整性保护
5.2.加密
5.2.1.对称加密(共享秘钥加密)
- 加密和解密使用同一个秘钥
存在问题:
5.2.2.非对称加密(公开密钥加密)
说明:非对称加密,很好的解决了对称加密的问题
特点
- 私有秘钥不能让其他人知道
- 公开密钥任何人都可以知道
过程
- 发送密文的一方使用对方的公开密钥进行加密处理
- 对方收到被加密的信息后,再使用自己的私有秘钥进行解密
存在问题:公开密钥是否是正确的?举例说明
- 接收者持有私钥,将自己的公开密钥公开后
- 若该公开密钥被攻击者替换掉了
- 发送者使用“假”的公开密钥进行加密后,将数据传输给接收者
- 若该消息被攻击者劫持,那么就可以解开“假”的公开密钥加密后的数据
5.2.3.CA机构颁发的公开密钥证书
作用:证明公开密钥正确性的证书(证明非对称加密的公开密钥是货真价实的公开密钥)
证明公开密钥的正确性,可以使用数字证书认证机构(CA,Certificate Authority)和相关机关颁发的公开密钥证书。
- 数字证书认证机构(CA,Certificate Authority):处于客户端和服务端双方都可信赖的第三方机构
CA为“服务端公开密钥”颁发公开密钥证书的过程
- 服务器把自己的公钥,登录给CA
- CA用自己的私钥,对服务器的公开密钥签署数字签名&&加密,颁发公钥证书
浏览器验证证书有效性的流程
- 前置条件:浏览器已经下载&安装了CA机构的公钥
- 浏览器拿到CA颁发的公钥证书后,使用CA机构的公钥解密,进而验证数字签名的真实性
5.3.HTTPS安全通信机制
HTTPS采用混合加密机制
- 非对称加密:交换秘钥阶段
- 对称加密:传输报文
- TCP三次握手
- SSL协议建立通信(四次握手)
- 前两次握手:协商加密组件
- ClientHello:客户端向服务器发起加密通信请求
- 客户端支持的SSL协议版本列表
- 客户端支持的密码套件列表,如RSA加密算法
- SeverHello:服务端收到客户端请求后,向客户端发出响应
- 确认SSL协议版本,如果浏览器不支持,则关闭加密通信
- 从客户端发来的密码套件列表中,选择一个密码套件
- 公开密钥证书(证书中也包含了公开密钥)
- ClientHello:客户端向服务器发起加密通信请求
- 后两次握手:通过非对称加密,确认后面用于通信的对称加密使用的[会话秘钥]
- 客户端回应
- 客户端收到服务器的回应后,首先验证公钥证书是否正确
- 如果证书没有问题,客户端会从数字证书中取出服务器的公钥,然后使用它加密报文,向服务器发送如下信息:
- 使用服务器发来的公开密钥,对数据加密,得到pre-master secret(通过pre-master secret可以计算出会话秘钥master secret)
- Change Cipher Spec报文(加密通信算法改变通知):表示随后的信息都将用[会话秘钥master secret]加密通信
- 客户端握手结束通知,同时把之前所有内容的发生的数据做个Sha1,用来供服务端校验
- 服务器的最后回应
- 服务器收到客户端加密后的随机数pre-master secret之后,使用私有秘钥解密;若解密成功,得到pre-master secret后,计算出[会话秘钥master secret]
- 然后,向客户端发送最后的信息
- 加密通信算法改变通知(Change Cipher Spec报文):表示随后的信息都将用[会话秘钥master secret]加密通信
- 服务器握手结束通知,同时把之前所有内容的发生的数据做个摘要,用来供客户端校验
- 客户端回应
- 前两次握手:协商加密组件
- SSL建立通信成功后,就使用对称加密的方式,进行通信
6.HTTP1.0、 HTTP1.1、HTTP2.0、HTTP3.0对比
6.1. HTTP2.0
多路复用
HTTP/2 是可以在一个连接中并发多个请求或回应,而不用按照顺序一一对应。
移除了 HTTP/1.1 中的串行请求,不需要排队等待,也就不会再出现「队头阻塞」问题,降低了延迟,大幅度提高了连接的利用率
头部压缩:HTTP/2 会压缩头(Header)如果你同时发出多个请求,他们的头是一样的或是相似的,那么,协议会帮你消除重复的部分
- 这就是所谓的
HPACK
算法:在客户端和服务器同时维护一张头信息表,所有字段都会存入这个表,生成一个索引号,以后就不发送同样字段了,只发送索引号,这样就提高速度了
二进制格式
HTTP/2 不再像 HTTP/1.1 里的纯文本形式的报文,而是全面采用了二进制格式,头信息和数据体都是二进制,并且统称为帧(frame):头信息帧(Headers Frame)和数据帧(Data Frame)
这样虽然对人不友好,但是对计算机非常友好,因为计算机只懂二进制,那么收到报文后,无需再将明文的报文转成二进制,而是直接解析二进制报文,这增加了数据传输的效率。
数据流 (stream)
HTTP/2 的数据包不是按顺序发送的,同一个连接里面连续的数据包,可能属于不同的回应。因此,必须要对数据包做标记,指出它属于哪个回应。
在 HTTP/2 中每个请求或相应的所有数据包,称为一个数据流(Stream
)。每个数据流都标记着一个独一无二的编号(Stream ID),不同 Stream 的帧是可以乱序发送的(因此可以并发不同的 Stream ),因为每个帧的头部会携带 Stream ID 信息,所以接收端可以通过 Stream ID 有序组装成 HTTP 消息
客户端和服务器双方都可以建立 Stream, Stream ID 也是有区别的,客户端建立的 Stream 必须是奇数号,而服务器建立的 Stream 必须是偶数号。
服务器推送
HTTP/2 还在一定程度上改善了传统的「请求 - 应答」工作模式,服务不再是被动地响应,也可以主动向客户端发送消息。
比如,客户端通过 HTTP/1.1 请求从服务器那获取到了 HTML 文件,而 HTML 可能还需要依赖 CSS 来渲染页面,这时客户端还要再发起获取 CSS 文件的请求,需要两次消息往返,如下图左边部分:
如上图右边部分,在 HTTP/2 中,客户端在访问 HTML 时,服务器可以直接主动推送 CSS 文件,减少了消息传递的次数
Q: HTTP2有什么缺陷?
A: HTTP/2 通过 Stream 的并发能力,解决了 HTTP/1 队头阻塞的问题,看似很完美了,但是 HTTP/2 还是存在“队头阻塞”的问题,只不过问题不是在 HTTP 这一层面,而是在 TCP 这一层!
- HTTP/2 是基于 TCP 协议来传输数据的,TCP 是字节流协议,TCP 层必须保证收到的字节数据是完整且连续的,这样内核才会将缓冲区里的数据返回给 HTTP 应用,那么当「前 1 个字节数据」没有到达时,后收到的字节数据只能存放在内核缓冲区里,只有等到这 1 个字节数据到达时,HTTP/2 应用层才能从内核中拿到数据,这就是 HTTP/2 队头阻塞问题
6.2. HTTP/3 做了哪些优化?
- HTTP/2 队头阻塞的问题是因为 TCP,所以 HTTP/3 把 HTTP 下层的 TCP 协议改成了 QUIC(HTTP/3 的一个重要区别是它在一种新的传输协议 QUIC 上运行)
- QUIC 的使用意味着 HTTP/3 依赖于UDP,而不是TCP。切换到 UDP 将使在线浏览时的连接速度和用户体验更快。
Quic协议
- 减少了 TCP 三次握手及 TLS 握手时间
- 改进的拥塞控制
- 避免队头阻塞的多路复用
- 连接迁移
- 前向冗余纠错