网络与协议 · 50/72
1. Ajax、Axios、Fetch 对比 2. Ajax 原理 3. Ajax 技术与实现 4. 常见的应用层协议 5. 浏览器缓存的存储位置 6. 从输入 URL 到页面显示的过程 7. Cache-Control 常见配置值 8. CDN 工作原理 9. 为什么推荐将静态资源放到 CDN 上 10. Cookie 的弊端 11. Cookie 的 Secure 属性设置 12. CORS 请求携带身份凭证的方法 13. CORS 跨域原理 14. 复杂请求预检检查内容 15. CORS 预检请求 16. CORS简单请求的条件 17. 简单请求为何无需预检 18. DNS 域名解析与网络请求路由 19. 什么是跨域 20. 什么是 DNS 劫持? 21. DNS 预解析优化网页加载速度 22. DNS 解析过程与优化 23. URL 参数为什么需要 encodeURIComponent 转码 24. Last-Modified 和 ETag 的区别 25. Fetch 发送两次请求的原因 26. 正向代理与反向代理 27. 前后端通信方式 28. GET请求能否上传图片 29. GET 请求的传参长度限制 30. HTTP 缓存策略 31. GET 与 POST 的区别 32. HTTP状态码301与302的区别 33. HTTP 数据传输 34. HTTP 队头阻塞 35. HTTP 请求头和响应头的重要字段 36. HTTP发展历程 37. HTTP与HTTPS总结 38. HTTP 和 HTTPS 的区别 39. HTTP 报文结构与状态码 40. HTTP Keep-Alive 机制 41. HTTP管道机制的作用 42. HTTP协议优缺点 43. HTTP 重定向状态码 301/302/303/307/308 44. HTTP 请求方法 45. HTTP 协议版本演进 46. HTTP与TCP的区别 47. HTTP/2 多路复用原理 48. HTTPS 协议的缺点 49. HTTP/3 如何保证传输可靠性 50. HTTP/2 的改进 51. HTTPS 加密原理 52. 什么是负载均衡? 53. Nginx 负载均衡调度算法 54. Nginx 是什么 55. 对象存储 OSS 是什么 56. OPTIONS 请求方法及使用场景 57. 轮询与 WebSocket 对比 58. HTTPS 中 SSL 的 OSI 层位置 59. SSL连接恢复 60. 强缓存和协商缓存 61. TCP 三次握手与四次挥手 62. TCP三次握手中的数据传输 63. TCP 和 HTTP 请求的关系 64. TCP/IP 协议 65. TCP 如何判断丢包 66. TCP 与 UDP 的区别 67. WebSocket 的 Handshaking 握手过程 68. TLS 1.3 相比 TLS 1.2 的改进 69. URI、URL、URN 的区别 70. WebSocket 心跳机制 71. WebSocket 协议原理 72. XML与JSON对比

HTTP/2 的改进

HTTP/2 相比 HTTP/1.1 的主要改进和优化

问题

HTTP/2 相比 HTTP/1.1 有哪些改进?

解答

HTTP/1.1 存在的问题

TCP 连接数限制

浏览器对同一域名最多只能同时创建 6~8 个 TCP 连接。为了突破限制,出现了域名分片技术(将资源放在不同子域名下),但这会带来额外的 DNS 查询、三次握手、慢启动等开销,占用更多 CPU 和内存,在移动端问题更明显。

线头阻塞(Head Of Line Blocking)

每个 TCP 连接同时只能处理一个请求-响应,浏览器按 FIFO 原则处理请求。如果前一个响应未返回,后续请求都会被阻塞。虽然出现了管线化(pipelining)技术,但存在诸多问题:第一个响应慢仍会阻塞后续响应、服务器需要缓存多个响应、中途断连需要重新处理多个请求,且需要客户端-代理-服务器都支持。

Header 冗余

每次请求的 Header 内容多且变化不大,没有压缩传输优化方案。

优化手段的副作用

为了减少请求数,需要合并文件、雪碧图、资源内联等优化,但这导致单个请求内容变大、延迟变高,且内嵌资源无法有效使用缓存。

明文传输

HTTP/1.1 明文传输存在安全隐患。

HTTP/2 的改进

二进制分帧层(Binary Framing Layer)

帧是数据传输的最小单位,使用二进制传输代替明文传输,原本的报文消息被划分为更小的数据帧。

多路复用(Multiplexing)

在一个 TCP 连接上可以不断发送帧,每帧通过 stream identifier 标识所属的流。接收方根据 stream identifier 拼接每个流的所有帧。

将 HTTP/1.1 的每个请求当作一个流,多个请求变成多个流,请求响应数据分成多个帧,不同流中的帧交错发送,实现了单连接上多请求-响应并行。这解决了线头阻塞问题,减少了 TCP 连接数量和慢启动造成的问题。HTTP/2 对同一域名只需创建一个连接。

服务端推送(Server Push)

服务器可以主动向浏览器推送与请求相关的资源,浏览器无需发起后续请求。相比 HTTP/1.1 资源内联的优势:

  • 客户端可以缓存推送的资源
  • 客户端可以拒收推送的资源
  • 推送资源可以由不同页面共享
  • 服务器可以按优先级推送资源

Header 压缩(HPACK)

使用 HPACK 算法压缩首部内容,减少传输数据量。

应用层重置连接

HTTP/1.1 通过设置 TCP segment 的 reset flag 来关闭连接,会直接断开连接。HTTP/2 引入 RST_STREAM 类型的帧,可以在不断开连接的前提下取消某个请求的流。

请求优先级

每个流都可以设置依赖(Dependency)和权重,按依赖树分配优先级,解决关键请求被阻塞的问题。

流量控制

每个流都有自己的流量窗口,可以限制对端发送数据。两端都必须告知对方剩余空间,在窗口扩大前,对端只能发送限定大小的数据。

HTTP/1.1 优化手段可以弃用

合并文件、内联资源、雪碧图、域名分片对 HTTP/2 来说不再必要。使用 HTTP/2 应尽可能将资源细粒化,文件分解得更散,不用担心请求数过多。

关键点

  • 二进制分帧和多路复用实现单连接并行传输,解决线头阻塞和连接数限制
  • 服务端推送允许主动推送资源,客户端可缓存、拒收或共享
  • HPACK 算法压缩 Header,流量控制和优先级设置优化传输效率
  • 应用层重置连接避免断开 TCP 连接的开销
  • 资源细粒化成为最佳实践,无需合并文件和域名分片