摘要
本文主要是HTTP/1.1以及HTTP/2和HTTP/3的一些要点,版本的更新都是为了升级和迭代旧版本。HTTP一直在不停的优化升级,以提高带宽利用和降低请求与响应的延迟。通过SSL\TLS协议加密HTTP传输数据,让传输数据更安全。
超文本传输协议HTTP
HTTP协议是客户端与Web服务器之间的应用层通信协议。从最开始用于万维网传输文本到现在传输多媒体资源。从HTTP/1.0最简单的一次请求对应一次TCP连接,再到HTTP/1.1在短时间内复用TCP连接进行持续传输数据,再到HTTP/2面向一次TCP连接全双攻交换所有数据,到目前HTTP/3基于改TCP为UDP数据报传输数据。HTTP一直在为了降低时延,提高响应和提高资源利用率而不停的优化和升级中。
HTTP/1.1版本
HTTP/1.0 作为HTTP的第一个版本,存在的两个主要问题:
- 每次请求,都需要建立TCP连接。这样旧的TCP无法复用,导致资源浪费。TCP三次握手建立连接和四次挥手断开都需要消耗性能。
head of line blocking
,导致带宽浪费。即第一个请求被阻塞,后续请求需要等待第一个响应报文,才能继续发送请求,这种就浪费了带宽,增加时延。
HTTP/1.1协议改进:
- 连接可复用,增加管线化技术。这样在复用TCP连接后,后续请求报文可以沿着连接发送给服务器,降低延迟。同时也会造成的问题,TCP连接在有限时间内会关闭,对于闲散的请求不合适,例如移动端;前面的请求阻塞导致后续请求也被搁置,浪费带宽。
- 支持响应分块。
- 缓存控制机制
- 内容协商机制,例如请求头协商编码,类型等等。
- 增加Host头,能够使不同域名配置在同一个IP地址的服务器上。
为了解决TCP连接没复用,HTTP/1.1在请求头加入Connection:Keep-Alive
,表示在一定时间内复用连接,具体时长服务端设置。如果要关闭连接复用需要显式的设置``Connection:Close`。但其实这种持续连接对浏览器请求来说作用比较大,因为浏览器在发起对一个网站链接请求时,很发出很多HTTP请求,那么对同个域名的请求就可以复用同个链接。而对移动端应用来说,HTTP请求一般比较分散。
目前HTTP/1.1广泛应用在互联网中,默认的HTTP请求与响应都基础HTTP/1.1。
请求报文格式:
HTTP报文分为两种:请求报文,响应报文。
在请求报文中,第一行称为请求行,分别由方法、URL、版本以及它们之间的空格组成。
- 方法 :即HTTP定义的
GET
、POST
、HEAD
、PUT
、DELETE
、OPTIONS
、TRACE
、CONNECT
。而最常见就是GET
和POST
。 - URL: 这里的URL是相对URL,就是去掉域名后剩下的相对路径。例如
http://xxm-sz.com/dreamter/http
,这里的URL就是dreamter/http
。 - 版本:现在普遍使用和默认都是HTTP/1.1版本,但在不久的将来,很快就升级到HTTP/2版本,甚至HTTP/3版本。
在请求行后便是首部行,通常由多条请求头组成,例如Connection: keep-alive
,Host:www.baidu.com
在首部行结束后,换行便是请求报文的数据部分,但不一定都会携带数据部分,例如GET
请求。
在响应报文中,第一行称为响应行,分别由版本、状态码、短语组成。版本对请求报文相对应。状态码表示服务器对请求报文的处理结果,而短语便是对状态码简短的秒速。
状态码都是三位数:
- 1xx表示通知信息,如请求收到了或正在进行处理。例如客户端发送请求报文中请求头携带:
Expect:100-Continue
,服务器一般要回复状态100的响应报文表示接受或者状态码417响应报文拒绝该报文。 - 2xx 表示成功,如接受了或知道了。常返回200表示成功。
- 3xx表示重定向,例如302重定向要Location的URL。
- 4xx表示客户端差错,例如404表示客户端请求的URL不存在。
- 5xx表示服务器差错。例如程序运行出异常。
响应头部与请求头类似,由键值对组成,如常见的Content-Encoding:gzip
,Connection:keep-alive
。响应报文的最后部分便是响应数据,同样也有可能不存在。
HTTP/2
HTTP/2 基于``SPDY`协议,客户端与服务器通信是全双工,意味着在建立连接后,不仅客户端可以请求服务器数据,服务器也可以主动推送信息到客户端。HTTP/1.1如果要并发请求,就需要建立多个TCP连接,就会消耗很多的资源,且大多数浏览器为了控制本地资源的使用情况会控制同个域名下TCP连接的数量。通过多路复用,所有通信都可以在单个连接完成,且无任何通信容量的限制。
在HTTP/2通信中建立起来的TCP连接就相当于一个流,每一个流都有自己的唯一标识符。而在流上交互的数据称为信息,由一个或多个二进制帧所组成,帧是通信的最小单元,帧最终在通信双方能按序组装成信息。
同时,在连接过程中,客户端和服务器会建立首部表
来缓存请求头和响应头,避免每次请求都要携带重复的请求头信息,起到压缩头部作用。
在Android上,只要服务器支持,通过OkHttp
已经完全可以支持HTTP/2.0了。
HTTP/3 之前版本基于TCP,享受TCP提供的数据可靠性传输,也要承担其带来的副作用,例如三次握手,四次挥手导致的时延,流量控制,拥塞机制导致传输效率有限。HTTP/3将运输层使用的TCP改为UDP用户数据报,通过QUIC保证稳定性。
SSL\TLS
安全套接字层SSL协议作用在端系统应用层HTTP和运输层之间,在TCP之上建立一个安全通道,为通过TCP传输的应用层数据提供安全保障。而运输层安全TLS是SSL协议的升级版本。
SSL/TLS提供的安全服务:
- 服务器鉴别,允许用户证实服务器的身份。通过服务器的证书来鉴别服务器身份和获得公钥。
- 客户鉴别,SSL的可选安全服务,允许服务器证实客户的身份。
- 加密的SSL会话,加密客户与服务器之间发送的所有信息。并检测报文是否被篡改。
工作简要流程:
- 协商算法。浏览器A向服务器B发送SSL的版本号和可选的加密算法。服务器B选择自己支持的算法(例如RSA),并告知A。
- 服务器鉴别。服务器B向客户端A发送包含其RSA公钥的数字证书,客户端A使用发布该证书的认证机构CA公开发布的RSA公钥对B的数字证实进行验证。
- 会话密钥计算。客户端A随机生成一个秘密数,用B的公钥加密后发送给B。双方根据协商的算法产生共享的对称会话密钥(即A和B分别用第一步确定的算法对秘密书进行计算生成会话密钥)。
- 安全数据传输。双方用会话密钥生加密和解密传输数据并验证完整性。
HTTPS
在HTTP1.1以文本形式,HTTP2以二进制形式传输数据,但两者都是明文传输数据,HTTP2只需借助特定工具就能翻译能明文。因为传输数据被第三方盗取后,非常容易获取传输内容。因此需要对HTTP所传输的数据进行加密,例如采用DES,RSA等加密算法。
HTTPS是在HTTP的基础上,通过SSL/TLS层与运输层TCP通信。也就是说:HTTPS=HTTP+SSL\TLS。
HTTP与HTTPS的区别:
1、HTTPS协议需要到ca申请证书。
2、HTTP是超文本传输协议,信息是明文传输,HTTPS则是具有安全性的SSl/TLS加密传输协议。
3、HTTP和HTTPS使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。
4、HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比HTTP协议安全。
HTTP缓存原理与机制
通过本地缓存机制,客户端在请求数据时,不必每次都需要向服务器拉去数据,而是先检查本地缓存是否可用。这样非常有力的提高客户端的响应速度。HTTP的缓存存在两种类型:强制缓存和协商缓存。
客户端可以在HTTP请求中使用的Cache-Control
指令:
- max-age:缓存有效期,超过设置的时间表示该缓存已经过期。
- max-stale:表明客户端愿意接收一个已经过期的资源。可以设置秒数,表示过期时长不能超过该秒数。
- min-fresh:客户端希望获取一个能在指定的秒数内保持其最新状态的响应
- no-cache:不缓存任何内容,包括请求报文和响应报文。
- nostore:发送缓存前,需要与服务器协商缓存验证。
- no-transform:不得对资源进行转换或转变。
Content-Encoding
、Content-Range
、Content-Type
等HTTP头不能由代理修改 - on-if-cached:表明客户端只接受已缓存的响应,并且不要向原始服务器检查是否有更新的拷贝。
服务器可以在响应中使用的Cache-Control
指令:
- must-revalidate:一旦资源过期(比如已经超过
max-age
),在成功向原始服务器验证之前,缓存不能用该资源响应后续请求。 - no-cache:发送缓存前,需要与服务器协商缓存验证。
- no-store:不缓存任何内容,包括请求报文和响应报文。
- no-transform:不得对资源进行转换或转变。
Content-Encoding
、Content-Range
、Content-Type
等HTTP头不能由代理修改。 - public 可缓存指令,表示响应报文可以被任何对象缓存。
- private 可缓存指令,表示响应报文只能被单个用户缓存,即客户端,不能作为共享缓存,例如代理服务器。
- proxy-revalidate:与must-revalidate作用相同,但它仅适用于共享缓存(例如代理),并被私有缓存忽略。
- max-age:缓存有效期,超过设置的时间表示该缓存已经过期。
- s-maxage:覆盖
max-age
或者Expires
头,但是仅适用于共享缓存(比如各个代理),私有缓存会忽略它。
当服务器的响应报文请求头携带max-age=xxx
,表示该报文数据在xxx
秒服务器不会更改,意味着在这段时间,如果客户端请求了相同的数据,则直接从本地缓存取数据即可,并不需要向服务器拉取数据。这就是强制缓存。
协商缓存指的是当Cache-Control:no-cache
或者本地缓存超过max-age=xxx
锁设置的时间,在获取本地缓存时,需要先将个缓存的标识Etag
发给服务器,由服务器验证该数据是否过期失效。如果失效,则返回新数据的且状态码为200的响应报文;如果未失效,返回状态码304的响应报文,告诉客户端使用本地缓存。
关于协商缓存流程:
- 第一次请求数据,响应报文会携带
Last-Modified
字段和Etag
标识字段,表示该数据在服务器最后修改时间和唯一标识,客户会缓存该数据。 - 在再请求相同数据时,客户端请求报文请求头会携带
If-Modified-Since
的字段和If-None-Match
字段,取值则分别是第一次服务器响应报文的Last-Modified
和Etag
的值。 - 服务器收到请求报文后,将
If-Modified-Since
的值与本地资源修改时间对比后。如果未被修改则返回状态码304的响应报文,否则返回状态码200的响应报文,并携带服务器修改后的本地资源。 - 客户端收到200的响应报文,则直接使用本地缓存。收到304的响应报文则使用报文中的数据,并缓存。
最后
相关参考资料
欢迎点赞+关注+评论三连击