了解HTTP(HyperText Transfer Protocol)

一、诞生

89年3月,CERN(欧洲核子研究组织)蒂姆• 伯纳斯 – 李(Tim BernersLee) 博士提出了一种能让远隔两地的研究者们共享知识的设想。理念:借助多文档之间相互关联形成的超文本 (HyperText),连成可相互参阅的 WWW(World Wide Web,万维网);
92年9月,第一个网站( www.ibarakiken.gr.jp/www/

二、传输过程

一个简单的HTTP报文(起始行、首部、主体):
request

图片[1]-了解HTTP(HyperText Transfer Protocol)-一一网
response

图片[2]-了解HTTP(HyperText Transfer Protocol)-一一网
传输过程:

三、发展

http0.9

  1. 只有一个命令GET

  2. 没有header等描述数据的信息

  3. 服务器发送完毕,就关闭TCP连接

http1.0

  1. 增加了status,code和header

  2. 多字符集,多部分发送,权限,缓存

  3. 缓存:If-Modified-Since,Expires

http1.1

  1. 持久连接keep-alive,复用TCP链接,时间由服务端控制,在一个TCP连接上可以传送多个HTTP请求和响应,减少了建立和关闭连接的消耗和延迟,在HTTP1.1中默认开启Connection: keep-alive,一定程度上弥补了HTTP1.0每次请求都要创建连接的缺点。

  2. 缓存:Entity tag,If-Unmodified-Since, If-Match, If-None-Match

  3. 断点续传: range

  4. Host头处理,在HTTP1.0中认为每台服务器都绑定一个唯一的IP地址,因此,请求消息中的URL并没有传递主机名(hostname)。但随着虚拟主机技术的发展,在一台物理服务器上可以存在多个虚拟主机(Multi-homed Web Servers),并且它们共享一个IP地址。HTTP1.1的请求消息和响应消息都应支持Host头域,且请求消息中如果没有Host头域会报告一个错误(400 Bad Request)。

http2

1. 二进制分帧/多路复用

所有数据以二进制传输,在 TCP 协议中,数据的传输单位是数据报。数据分成两大部分。头部(header) 和 实际数据部分(body)。在 HTTP 2.0 中,它把数据报的两大部分分成了 header frame 和 data frame。也就是头部帧和数据体帧。帧的传输最终在流(Stream)中进行,
同一个连接里面发送多个请求不再需要按照顺序来。

图片[3]-了解HTTP(HyperText Transfer Protocol)-一一网
HTTP2中二进制协议的基本单元叫 frame(帧),不同frame 有不同作用,如:

  1. SETTING 帧:建立连接时,向对方传达一些配置信息如是否开启 server push 功能、最大帧 size等等;

  2. HEADERS 帧:发送 http 的 request 或者response的头部;

  3. CONTINUATION 帧:headers 要跨越多个帧,用此来指示头部上一个 HEADERS ;本质就是 HEADERS 帧,但是为了轻松处理,就用明确的类型来区分这种情况;

  4. DATA 帧:发送body数据用;

  5. PUSH_PROMISE 帧:用来告知对端初始化哪些数据,服务于 server push 功能

  6. WINDOW_UPDATE 帧:用来做流量控制。

流代表了一个完整的请求-响应数据交互过程。它具有如下几个特点:

  1. 双向性:同一个流内,可同时发送和接受数据。

  2. 有序性:流中被传输的数据就是二进制帧 。帧在流上的被发送与被接收都是按照顺序进行的。

  3. 并行性:流中的 二进制帧 都是被并行传输的,无需按顺序等待。但却不会引起数据混乱,因为每个帧都有顺序标号。它们最终会被按照顺序标号来合并。

  4. 流的创建:流可以被客户端或服务器单方面建立, 使用或共享。

  5. 流的关闭:流也可以被任意一方关闭。

2. 服务端推送

服务端可以在发送页面HTML时主动推送其它资源,而不用等到浏览器解析到相应位置,发起请求再响应。例如服务端可以主动把JS和CSS文件推送给客户端,而不需要客户端解析HTML时再发送这些请求。
服务端可以主动推送,客户端也有权利选择是否接收。如果服务端推送的资源已经被浏览器缓存过,浏览器可以通过发送RST_STREAM帧来拒收。主动推送也遵守同源策略,服务器不会随便推送第三方资源给客户端。

3. 头部压缩(HPACK)

HTTP1.x的header很多时候都是重复多余的。选择合适的压缩算法可以减小包的大小和数量。通过静态 Huffman 代码对传输的标头字段进行编码,从而减小了各个传输的大小。客户端和服务器同时维护和更新一个包含之前见过的header的索引列表(换句话说,它可以建立一个共享的压缩上下文),此列表随后会用作参考,对之前传输的值进行有效编码。利用 Huffman 编码,可以在传输时对各个值进行压缩,而利用之前传输值的索引列表,我们可以通过传输索引值的方式对重复值进行编码,索引值可用于有效查询和重构完整的header键值对。

  • 消息发送端和消息接受端共同维护一份静态表和一份动态表(这两个合起来充当 字典 的角色),

  • 每次请求时,发送方根据字典的内容以及一些特定指定,编码压缩消息头部,

  • 接收方根据字典进行解码,并且根据指令来判断是否需要更新动态表

4. 其他

http2.0并没有改变http1.x的语义,只是把原来http1.x的header和body部分用frame重新封装了一层而已,HTTP2向下兼容,需确认server是否支持2.0,这一过程一般在ssl握手阶段完成,http2叫ALPN(Application Layer Protocol Negotiation),SPDY叫NPN (Next Protocol Negotiation)。

5. 与http1.*对比

http2加载速度对比http1.1

HTTP2.0的多路复用和HTTP1.X中的长连接复用有什么区别?
HTTP/1.* 一次请求-响应,建立一个连接,用完关闭;每一个请求都要建立一个连接;HTTP/1.1,Pipeling解决方式为,若干个请求排队串行化单线程处理,后面的请求等待前面请求的返回才能获得执行机会,一旦有某请求超时等,后续请求只能被阻塞。( Pipeling条件苛刻 ,只有幂等的请求(GET,HEAD)能使用pipelining,非幂等请求比如POST不能使用,且中间路由支持参差不齐,最终的结果可能反而使页面访问速度下降,所以浏览器一般都是直接建立多个TCP链接)。
HTTP/2多个请求可同时在一个连接上并行执行。某个请求任务耗时严重,不会影响到其它连接的正常执行,但丢包同样会阻塞后面的请求,HTTP2通过streamID来区分一个TCP链接中的不同请求。

HTTP3(QUIC(Quick UDP Internet Connection))

  • 实现了类似 TCP 的流量控制、传输可靠性的功能。虽然 UDP 不提供可靠性的传输,但 QUIC 在 UDP 的基础之上增加了一层来保证数据可靠性传输。它提供了数据包重传、拥塞控制以及其他一些 TCP 中存在的特性。

  • 集成了 TLS 加密功能。目前 QUIC 使用的是 TLS1.3,相较于早期版本 TLS1.3 有更多的优点,其中最重要的一点是减少了握手所花费的 RTT 个数。

  • 实现了 HTTP/2 中的多路复用功能。和 TCP 不同,QUIC 实现了在同一物理连接上可以有多个独立的逻辑数据流。实现了数据流的单独传输,就解决了 TCP 中队头阻塞的问题。

参考
juejin.im/post/5b88a4…
segmentfault.com/a/119000001…

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享