前端 & AI 面试题库
Browser

HTTP 1、2、3 的区别

HTTP/1.1、HTTP/2、HTTP/3 的区别是什么?

核心答案

HTTP 协议经历了多个版本的演进,每个版本都在性能、安全性和功能上有所改进。

HTTP/1.1(1997年)

特点

  • 文本协议:请求和响应都是文本格式
  • 请求-响应模型:客户端发送请求,服务器返回响应
  • 连接复用:支持 Keep-Alive,可以在一个连接上发送多个请求
  • 队头阻塞:同一连接上的请求必须按顺序响应

问题

请求1 → 等待响应1 → 请求2 → 等待响应2 → 请求3
  • 如果响应1慢,会阻塞后续请求
  • 浏览器通常为每个域名建立 6 个连接来缓解问题

示例

GET /api/data1 HTTP/1.1
Host: example.com

GET /api/data2 HTTP/1.1
Host: example.com

HTTP/2(2015年)

核心特性

1. 二进制分帧(Binary Framing)

  • 使用二进制格式传输,不再是文本
  • 将数据分割成更小的帧(Frame)
  • 每个帧都有类型和流标识

2. 多路复用(Multiplexing)

  • 一个连接可以并行处理多个请求/响应
  • 解决了 HTTP/1.1 的队头阻塞问题
  • 请求和响应可以交错传输

3. 头部压缩(HPACK)

  • 使用 HPACK 算法压缩请求头
  • 减少重复传输的头部信息
  • 显著减少头部大小

4. 服务器推送(Server Push)

  • 服务器可以主动推送资源给客户端
  • 减少客户端请求次数
  • 提前推送可能需要的资源

5. 流优先级(Stream Prioritization)

  • 可以为不同的流设置优先级
  • 重要资源优先传输

优势

HTTP/1.1:串行请求,需要多个连接
HTTP/2:并行请求,单个连接,性能更好

示例

# HTTP/2 可以在一个连接上并行传输
流1: 请求1 → 响应1
流2: 请求2 → 响应2
流3: 请求3 → 响应3
(可以交错传输)

HTTP/3(2020年)

核心特性

1. 基于 UDP 的 QUIC 协议

  • 不再使用 TCP,改用 UDP
  • QUIC(Quick UDP Internet Connections)协议
  • 解决 TCP 的队头阻塞问题

2. 内置加密

  • TLS 1.3 内置在 QUIC 中
  • 所有数据默认加密
  • 减少握手次数

3. 连接迁移

  • 切换网络时保持连接
  • IP 地址改变不影响连接
  • 更好的移动网络支持

4. 0-RTT 连接建立

  • 首次连接:1-RTT
  • 后续连接:0-RTT(使用之前建立的连接信息)

5. 改进的多路复用

  • 基于流的传输
  • 每个流独立,互不影响
  • 彻底解决队头阻塞

优势对比

特性HTTP/1.1HTTP/2HTTP/3
传输协议TCPTCPUDP (QUIC)
多路复用
头部压缩✅ (HPACK)✅ (QPACK)
服务器推送
队头阻塞TCP 层仍有
加密可选 (HTTPS)可选 (HTTPS)内置
连接迁移
0-RTT

性能对比

HTTP/1.1

  • 需要多个连接(通常 6 个)
  • 队头阻塞严重
  • 头部重复传输

HTTP/2

  • 单个连接,多路复用
  • 头部压缩
  • 性能提升 20-50%

HTTP/3

  • 基于 UDP,延迟更低
  • 无队头阻塞
  • 连接迁移
  • 性能提升 30-60%

延伸追问

1. HTTP/2 的队头阻塞问题?

回答:HTTP/2 虽然解决了应用层的队头阻塞,但 TCP 层仍有队头阻塞:

问题

  • TCP 按顺序传输数据包
  • 如果某个数据包丢失,后续数据包需要等待
  • 影响整个连接的性能

示例

数据包1、2、3、4、5
如果数据包2丢失:
- 数据包3、4、5需要等待
- 即使它们属于不同的流

HTTP/3 的解决方案

  • 使用 UDP,每个流独立
  • 一个流的数据包丢失不影响其他流

2. HTTP/2 的服务器推送如何使用?

回答:服务器推送示例:

服务器端

// Node.js 示例
const http2 = require('http2');

const server = http2.createServer();

server.on('stream', (stream, headers) => {
  if (headers[':path'] === '/index.html') {
    // 推送 CSS 文件
    stream.pushStream({ ':path': '/style.css' }, (err, pushStream) => {
      pushStream.respond({ ':status': 200 });
      pushStream.end(fs.readFileSync('style.css'));
    });
    
    // 返回 HTML
    stream.respond({ ':status': 200 });
    stream.end(fs.readFileSync('index.html'));
  }
});

客户端处理

// 浏览器自动处理推送的资源
// 如果资源已经在缓存中,可以拒绝推送

注意事项

  • 推送的资源可能客户端不需要
  • 需要合理使用,避免浪费带宽
  • HTTP/3 中服务器推送被移除(因为效果不佳)

3. HTTP/3 为什么使用 UDP?

回答:使用 UDP 的原因:

1. TCP 的局限性

  • TCP 的队头阻塞问题
  • 连接建立需要三次握手
  • 连接迁移困难

2. UDP 的优势

  • 无连接,延迟低
  • 可以自定义传输逻辑
  • QUIC 在 UDP 上实现了可靠传输

3. QUIC 协议

  • 在 UDP 上实现了类似 TCP 的可靠传输
  • 内置加密和拥塞控制
  • 解决了 TCP 的问题

4. 兼容性

  • UDP 被广泛支持
  • 不需要修改网络基础设施
  • 更容易部署

4. 如何检测网站使用的 HTTP 版本?

回答:检测方法:

1. 浏览器开发者工具

  • Network 面板查看 Protocol 列
  • 显示 h2(HTTP/2)或 h3(HTTP/3)

2. 命令行工具

# 使用 curl
curl -I --http2 https://example.com
curl -I --http3 https://example.com

# 使用 openssl
openssl s_client -connect example.com:443 -alpn h2,h3

3. 在线工具

5. 如何升级到 HTTP/2 或 HTTP/3?

回答:升级步骤:

HTTP/2

  1. 使用 HTTPS:HTTP/2 要求 HTTPS(浏览器实现)
  2. 服务器支持:Nginx、Apache 等支持 HTTP/2
  3. 配置服务器
# Nginx 配置
listen 443 ssl http2;

HTTP/3

  1. 服务器支持:需要支持 QUIC 的服务器(如 Cloudflare)
  2. 配置
# Nginx 1.25+ 支持 HTTP/3
listen 443 quic reuseport;
listen 443 ssl http2;
add_header Alt-Svc 'h3=":443"';

CDN 支持

  • Cloudflare:自动支持 HTTP/3
  • 其他 CDN:需要配置启用

(注:文档部分内容可能由 AI 生成)