HTTP协议发展过程
Contents
http 基本流程
- TCP Connect
- Request
- Response
- TCP Close
http 发展过程
http/0.9
- 最早诞生于 1991 年
- 极其简单,没有 http 头, 没有状态码,没有版本号
- 请求只支持 Get 方法,请求只有一行
GET /hello.html
- 响应也非常简单,只包含 html 文档本身
- 由于没有状态码和错误码,如果服务器处理发生错误时,就只会传回一个特殊的包含问题描述信息的 html 文件。
http/1.0
- 1996 年, http/1.0 版本发布
- 丰富了 http 传输内容(文字、图片、视频,不限于超文本)
- 为请求与响应添加了
http 头
- 协议
版本信息
需要随着 Request 一起发送 - Resuest 支持
HEAD
,GET
,POST
等方法 - 增加了
状态码
,响应对象的一开始是一个响应状态行
http/1.1
- http/1.0发布几个月之后,http/1.1就发布了,主要是对http/1.0的完善和优化
- 支持
长连接
(复用连接):服务器发出响应后,让TCP连接继续打开着(本来客户端是要关闭TCP连接的),同一对客户端/服务器之间的后续请求都可以通过这个连接发送。因为 TCP 连接长时间不关闭,服务器必须在内存里保存它的状态,这就占用了服务器的资源,所以长连接算是牺牲空间换时间
. - Request 和 Response 都支持
Host 头域
:在http/1.0中认为每台服务器都绑定一个唯一的ip, 所以Request的URL并没有传递主机名;但随着虚拟机技术的发展,在一台物理机上可以存在多台虚拟机,且他们共享一个ip,此时Host头域就很有必要了。 - chunked编码传输:http/1.0需要在响应头中设置完整的数据大小;但是随着发展,服务器中的很多内容是动态生成的,这就导致了浏览器不知道什么时候会接收完所有数据;通常,HTTP应答消息中发送的数据是整个发送的,Content-Length消息头字段表示数据的长度。数据的长度很重要,因为客户端需要知道哪里是应答消息的结束,以及后续应答消息的开始。 为了解决这个问题,http/1.1引入了chunk transfer机制:服务器会将数据分割成若干个任意大小的数据 块,每个数据块发送时会附上上个数据块的⻓度,最后使用一个零⻓度的块作为发送数据完成的标志。这样 就提供了对动态内容的支持。【用以支持动态内容】
- 增加pipeline:若不带pipeline,客户端只有在收到前一个请求的响应后,才发出新的请求;带pipeline之后,可以不等待前一个的响应而立即发送请求,减少RTT延迟【pipeline尝试解决队头阻塞问题(请求队列中,前面的请求处理慢了,后面的就只能等待),但是虽然请求可以很快发送,但是处理仍然是串行处理的,所以并没有真正解决行头阻塞问题,http/2.0的多路复用可以解决这个问题】。
- 引入内容协商机制:包括语言,编码类型等,允许客户端和服务器之间约定以最合适的内容进行交换
- 引入更多缓存机制:etag, cache-control等
- 仍然存在的问题
- 传输是明文,不够安全(https)
- header内容过大,造成宽带浪费(header压缩)
http/2.0
- 2015年, http/2.0 问世
- 使用
二进制分帧
:在应用层和传输层之间增加一个二进制分帧层
,在不改变http语义、http方法、状态码、URI、及首部字段的情况下,突破http/1.1的性能限制,改进传输性能,实现低延迟和高吞吐量。在二进制分帧层上,http/2.0 会将所有传输的信息分割为更小的消息和帧,并对它们采用二进制格式的编码,其中 http/1.x 的首部信息会被封装到 Headers 帧,而 request body 则封装到 Date 帧里面。 多路复用
:http/1.0有了长连接,而且浏览器每每个域名最多同时维护6个长连接;而http/2.0则是对一个域名只使用一个TCP长连接来传输数据,这样整个过程页面资源下载的过程只需要一次慢启动,同时避免了多个TCP长连接竞争带来的宽带问题;http/2.0同时采用了多路复用
的方式,可以并行发送多个请求,提高宽带利用率,解决行头等待
问题。【多路复用通过为每个请求添加一个id,然后在讲每个请求在二进制分帧层分为若干个带有请求id编号的帧,服务器端接收到帧之后再合成为一个完整的请求,从而实现请求的并发发送;同样,响应也是如此,加编号,分帧,并发发送】- 数据流优先级:由于请求可以并发发送了,那么如果出现了浏览器在等待关键的 CSS 或者 JS 文件完成对页面的渲染时,服务器却在专注的发送图片资源的情况怎么办呢?http/2.0 对数据流可以设置优先值,这个优先值决定了客户端和服务端处理不同的流采用不同的优先级策略。
- 服务端推送:在 http/2.0 中,服务器可以向客户发送请求之外的内容,比如正在请求一个页面时,服务器会把页面相关的 logo,CSS 等文件直接推送到客户端,而不会等到请求来的时候再发送,因为服务器认为客户端会用到这些东西。这相当于在一个 html 文档内集合了所有的资源。【省去了重复请求;服务推送是建立在长连接之上的,维护一个长连接需要心跳机制(一般为了节省服务器内存,一个长连接一段时间内没有连接的化会自动删除,所以需要客户端不断发送消息来维持长连接);手机要比PC更难维护一个长连接,因为手机使用的是移动互联网,并没有真正的ip,而是运营商分配的内网ip,详细原因可见: https://www.cnblogs.com/yorkyang/p/6305749.html
- 头部压缩:在http/1.0中,消息主体都会经过压缩,但状态行和头部却没有经过任何压缩,直接以纯文本传输,随着web页面越来越复杂,请求越来越多,消耗在头部的流量也会越来越多。所以http/2.0中对头部进行了压缩;http2.0采用的是hpak压缩算法。 https://juejin.im/post/5e7058be6fb9a07c89152313 https://segmentfault.com/a/1190000017011816
- http/2.0是基于SPDY设计的,但主要由两点不同
- http/2.0 支持明文 http 传输,而 SPDY 强制使用 https。
- http/2.0 消息头的压缩算法采用 hpack,而非 SPDY 采用的 deflate。
https
- https = http + SSL/TLS
- https端口为
443
, http端口号为80
- 一句话概括https,再讲一下为什么这么做?
- https就是用
对称加密
对传输信息进行加密,用非对称加密
+hash算法
进行认证和防止篡改,用权威第三方的数字证书
传输公钥; - http存在三大风险
- 被窃听的风险:加密
- 被篡改的风险:认证(非对称加密+hash算法)
- 被冒充的风险:数字证书
- 非对称加密虽然安全性能高,但计算量庞大,比较消耗性能,所以https采用对称加密和非对称加密结合的方式;
- 加密:对称加密,常用对称加密算法有:AES,DES,3DES等
- 认证:首先利用哈希算法(MD5,SHA1等)得到传输内容的一个信息摘要,以防被篡改;然后用私钥对信息摘要进行加密,得到一个数字签名,确保信息确实是服务器发送的;
- 数字证书:加密和认证都是建立在浏览器知道服务器的公钥的基础之上;为了将服务器的公钥正确地交到浏览器手上,引入了数字证书;数字证书的本质是一个第三方权威机构,同样利用了非对称加密以及数字签名的原理;【数字证书被伪造?申请证书需要验证域名,而且数字证书中不只有公钥,还有一些其他信息,比如网站域名等内容】
- https就是用
- 通信过程
- 浏览器向服务器的443端口发起请求,请求携带了浏览器支持的
加密算法
和哈希算法
- 服务器收到请求,选择浏览器支持的加密算法和哈希算法,并将
数字证书
返回给浏览器 - 浏览器收到数字证书,并进行证书认证,得到服务器的
公钥
; - 浏览器生成一个随机数R(对称密钥),用公钥对R加密,并传给服务器;
- 服务器收到消息,用自己的私钥解密得到R。
- 服务器以R为密钥加密网页内容,然后通过哈希算法得到加密内容的一个信息摘要,用私钥对信息摘要加密,并将加密信息和加密之后的信息摘要一起传给浏览器;
- 浏览器接收到数据,然后通过哈希算法得到加密内容的信息摘要,用公钥解密被加密的信息摘要对比自己生成的信息摘要和传过来的信息摘要,防止信息内容被篡改,如果信息内容没有被篡改,则对加密内容进行解密,得到网页;
- 浏览器向服务器的443端口发起请求,请求携带了浏览器支持的
Author 段新朋
LastMod 2020-07-28