HTTP1.0、HTTP1.1、HTTP2.0的关系和区别

一、汇总对比

HTTP0.9

HTTP/0.9 是 1991 年发布的第一个版本,只支持一种请求方式 — GET,没有 HTTP 请求头,没有状态码,也没有版本号。 后来它的版本号才被定义成 0.9,用来和其他版本的 HTTP 区分。

HTTP/0.9 的请求只有一行:

GET /hello.html

响应也是非常简单的,只包含 html 文档本身:

<HTML>
    Hello world
</HTML>

当 TCP 建立连接之后,服务器向客户端发送 HTML 格式的字符串,发送完毕后,就关闭 TCP 连接。由于没有状态码和错误代码,如果服务器处理的时候发生错误,只会传回一个包含问题描述信息的特殊的 HTML 文件。

此时的 HTTP 是无状态的,无状态是指对事务处理没有记忆能力,如果后续处理需要前面的信息,就必须重传。比如说访问一个网站需要反复进行登录操作。

HTTP1.0

  • 无连接
  • 引入了 POST 命令和 HEAD 命令
  • 请求与响应支持 HTTP 头,增加了状态码
  • 传输 HTML 文件以外其他类型的内容

HTTP1.1

  • 持久连接
  • 请求管道化(是将多个 HTTP 请求整批提交的技术)
  • 增加缓存处理(新的字段如cache-control)
  • 增加Host字段、支持断点传输等(把文件分成几部分)
  • 新增了 OPTIONS、PUT、 DELETE、TRACE、CONNECT 命令

HTTP2.0

  • 二进制分帧
  • 多路复用(或连接共享)
  • 头部压缩
  • 服务器推送

二、HTTP1.0:

浏览器的每次请求都需要与服务器建立一个TCP连接,服务器处理完成后立即断开TCP连接(无连接),服务器不跟踪每个客户端也不记录过去的请求(无状态)。

相比 HTTP/0.9,HTTP/1.0 主要有如下特性:

  • 丰富了传输内容,支持传输 HTML 文件以外其他类型的内容(文字、图片、视频);
  • 除了 GET 命令外,还引入了 POST 命令和 HEAD 命令;
  • 请求与响应支持 HTTP 头,增加了状态码,响应数据的一开始是一个响应状态行;

三、HTTP1.1:

HTTP/1.0中默认使用Connection: close。在HTTP/1.1中已经默认使用Connection: keep-alive,避免了连接建立和释放的开销,但服务器必须按照客户端请求的先后顺序依次回送相应的结果,以保证客户端能够区分出每次请求的响应内容。通过Content-Length字段来判断当前请求的数据是否已经全部接收。不允许同时存在两个并行的响应

  • 可以在一个 http 链接上同时发送多个请求 (可以克服同域并行连接限制带来的阻塞)
  • 服务器可以同时处理多个请求,但是必须按照请求的顺序返回结果(即使后面的请求先处理完成也还是需要缓存起来,等前面的请求处理完返回之后再返回)

可以复用连接;

  • 增加 pipeline:HTTP 管线化是将多个 HTTP 请求整批提交的技术,而在传送过程中不需先等待服务端的回应。管线化机制须通过永久连接(persistent connection)完成。 浏览器将 HTTP 请求大批提交可大幅缩短页面的加载时间,特别是在传输延迟(lag/latency)较高的情况下。有一点需要注意的是,只有幂等的请求可以使用 pipeline,如 GET,HEAD 方法。
  • chunked 编码传输:该编码将实体分块传送并逐块标明长度,直到长度为 0 块表示传输结束, 这在实体长度未知时特别有用(比如由数据库动态产生的数据);
  • 引入更多缓存控制机制:如 etag,cache-control - 引入内容协商机制,包括语言,编码,类型等,并允许客户端和服务器之间约定以最合适的内容进行交换;
  • 请求消息和响应消息都支持 Host 头域:在 HTTP 1.0 中认为每台服务器都绑定一个唯一的 IP 地址,因此,请求消息中的 URL 并没有传递主机名(hostname)。但随着虚拟主机技术的发展,在一台物理服务器上可以存在多个虚拟主机(Multi-homed Web Servers),并且它们共享一个 IP 地址。因此,Host 头的引入就很有必要了;
  • 新增了 OPTIONS、PUT、 DELETE、TRACE、CONNECT 命令;

四、HTTP2.0:

HTTP/2引入二进制数据帧和流的概念,其中帧对数据进行顺序标识,如下图所示,这样浏览器收到数据之后,就可以按照序列对数据进行合并,而不会出现合并后数据错乱的情况。同样是因为有了序列,服务器就可以并行的传输数据,这就是流所做的事情

概念 解释
流(stream) 已建立连接上的双向字节流
消息 与逻辑消息对应的完整的一系列数据帧
HTTP2.0通信的最小单位,每个帧包含帧头部,至少也会标识出当前帧所属的流(stream id)。

流: 存在于连接中的一个虚拟通道。流可以承载双向消息,每个流都有一个唯一的整数 ID。
HTTP/2 长连接中的数据包是不按请求-响应顺序发送的,一个完整的请求或响应(称一个数据流 stream,每个数据流都有一个独一无二的编号)可能会分成非连续多次发送。它具有如下几个特点:

双向性:同一个流内,可同时发送和接受数据。
有序性:流中被传输的数据就是二进制帧 。帧在流上的被发送与被接收都是按照顺序进行的。
并行性:流中的 二进制帧 都是被并行传输的,无需按顺序等待。
流的创建:流可以被客户端或服务器单方面建立, 使用或共享。
流的关闭:流也可以被任意一方关闭。
HEADERS 帧在 DATA 帧前面。
流的 ID 都是奇数,说明是由客户端发起的,这是标准规定的,那么服务端发起的就是偶数了。

多路复用:

1、所有的HTTP2.0通信都在一个TCP连接上完成,这个连接可以承载任意数量的双向数据流。

2、每个数据流以消息的形式发送,而消息由一或多个帧组成。这些帧可以乱序发送,然后再根据每个帧头部的流标识符(stream id)重新组装。

举个例子,每个请求是一个数据流,数据流以消息的方式发送,而消息又分为多个帧,帧头部记录着stream id用来标识所属的数据流,不同属的帧可以在连接中随机混杂在一起。接收方可以根据stream id将帧再归属到各自不同的请求当中去。

3、另外,多路复用(连接共享)可能会导致关键请求被阻塞。HTTP2.0里每个数据流都可以设置优先级和依赖,优先级高的数据流会被服务器优先处理和返回给客户端,数据流还可以依赖其他的子数据流。

4、可见,HTTP2.0实现了真正的并行传输,它能够在一个TCP上进行任意数量HTTP请求。而这个强大的功能则是基于“二进制分帧”的特性。

头部压缩

在HTTP1.x中,头部元数据都是以纯文本的形式发送的,通常会给每个请求增加500~800字节的负荷。

HTTP2.0使用encoder来减少需要传输的header大小,通讯双方各自cache一份header fields表,既避免了重复header的传输,又减小了需要传输的大小。高效的压缩算法可以很大的压缩header,减少发送包的数量从而降低延迟。

现在打开一个网页上百个请求已是常态,而每个请求带的一些首部字段都是相同的,例如cookie、user-agent等。HTTP2为此采用HPACK压缩格式来压缩首部。
头部压缩需要在浏览器和服务器端之间:

维护一份相同的静态字典,包含常见的头部名称,以及常见的头部名称和值的组合
维护一份相同的动态字典,可以动态的添加内容
通过静态Huffman编码对传输的首部字段进行编码

HTTP2的静态字典是长这个样子的(只截取了部分,完整表格在这里):
所以我们在传输首部字段的时候,例如要传输method:GET,那我们只需要传输静态字典里面method:GET对应的索引值就可以了,一个字节搞定。像user-agent、cookie这种静态字典里面只有首部名称而没有值的首部,第一次传输需要user-agent在静态字典中的索引以及他的值,值会采用静态Huffman编码来减小体积。

第一次传输过user-agent 之后呢,浏览器和服务器端就会把它添加到自己的动态字典中。后续传输就可以传输索引了,一个字节搞定。

我们用WireShark来抓包验证一下:
HTTP2目前都是HTTPS的请求,WireShark对HTTPS网站抓包解密请参考这里

  • 首次传输user-agent和第二次传输user-agent

由于第一次传输的时候,字典里面并没有user-agent的值,这时候user-agent是63字节,第二次传输时,他已经在动态字典里面了,只传索引,一个字节搞定。

  • HPACK的首部压缩力度

Header解码后的长度有471个字节,而HEADERS流只有246个字节。这只是第一个请求,后续的请求压缩力度会更大,因为前面请求用到的首部(静态字典中没有的)会添加到动态字典中,使得后续请求只需要传输字典里面的索引。

服务器推送:

服务器除了对最初请求的响应外,服务器还可以额外的向客户端推送资源,而无需客户端明确的请求。

服务器端推送使得服务器可以预测客户端需要的资源,主动推送到客户端。
例如:客户端请求index.html,服务器端能够额外推送script.js和style.css。
实现原理就是客户端发出页面请求时,服务器端能够分析这个页面所依赖的其他资源,主动推送到客户端的缓存,当客户端收到原始网页的请求时,它需要的资源已经位于缓存。
针对每一个希望发送的资源,服务器会发送一个PUSH_PROMISE帧,客户端可以通过发送RST_STREAM帧来拒绝推送(当资源已经位于缓存)。这一步的操作先于父响应(index.html),客户端了解到服务器端打算推送哪些资源,就不会再为这些资源创建重复请求。当客户端收到index.html的响应时,script.js和style.css已经位于缓存。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,189评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,577评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,857评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,703评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,705评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,620评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,995评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,656评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,898评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,639评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,720评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,395评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,982评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,953评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,195评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,907评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,472评论 2 342