一文搞懂http1,http2,http3,面试官说:就你了

790 阅读6分钟

对于前端的朋友们,对http协议深入了解是必须的知识点,http协议经历了多次的版本迭代,下面来聊一聊,从http1到http2到http3的发展。

1. http/1.1

  • 原理: HTTP/1.1 是基于请求-响应模型的文本协议。每个请求都需要建立一个独立的连接,每个连接只能处理一个请求。这导致了连接的不断建立和关闭,可能导致性能瓶颈。

  • 特点:

    1. 串行处理: 请求和响应是串行处理的,一个请求需要等待前一个请求完成后才能进行。
    2. 无连接复用: 每个资源都需要单独的请求,连接不能复用,可能导致延迟。
    3. 文本协议: 使用文本格式传输数据,头部信息相对冗长。
    4. 无头部压缩: 每个请求和响应都携带完整的头部信息,可能导致不必要的数据传输。

2. http/2

  • 原理: HTTP/2 采用了二进制协议,不再是文本协议。它引入了多路复用(Multiplexing),允许在一个连接上同时发送多个请求和响应。头部压缩减小了传输时的数据量。
  • 特点:
    1. 多路复用: 允许多个请求和响应同时在一个连接上传输,解决了连接复用的问题。
    2. 头部压缩: 减小了传输时的数据量,提高了效率。
    3. 二进制协议: 更高效的数据传输,降低了解析的复杂性。
    4. 服务器推送: 允许服务器在客户端请求之前主动推送资源。

3. http/3

  • 原理: HTTP/3 使用 QUIC 协议,基于 UDP,目的是提供更低的连接建立和数据传输延迟。QUIC 具有内置的加密,支持多路复用,类似于 HTTP/2,但更加灵活。
  • 特点:
    1. QUIC 协议: 使用 UDP 协议,避免了 TCP 的握手延迟,加速了连接建立。
    2. 多路复用: 与 HTTP/2 一样,支持多个请求和响应同时在一个连接上传输。
    3. 头部压缩: 类似于 HTTP/2,减小了传输时的数据量。
    4. 连接迁移: 允许在不同网络条件下无缝切换连接,提高了可靠性。
    5. 零往返时间(0-RTT)连接: 支持零往返时间握手,进一步减小连接建立时的延迟。

4.兼容性

HTTP/1.1:

  • 浏览器兼容性: HTTP/1.1几乎在所有现代浏览器中得到支持,包括Chrome、Firefox、Safari、Edge等。事实上,HTTP/1.1是Web的基础协议,几乎所有浏览器都支持它。
  • 服务器兼容性: 所有常见的Web服务器,如Nginx、Apache、Microsoft IIS等,都支持HTTP/1.1。

HTTP/2:

  • 浏览器兼容性: 主流浏览器(Chrome、Firefox、Safari、Edge等)已经广泛支持HTTP/2。这意味着,如果您的网站启用了HTTPS,浏览器会尽可能使用HTTP/2。
  • 服务器兼容性: Nginx、Apache等主要的Web服务器都支持HTTP/2。要启用HTTP/2,您需要确保服务器软件和相关模块是最新版本。

HTTP/3:

  • 浏览器兼容性: HTTP/3的支持在现代浏览器中逐渐增加。Chrome、Firefox、Safari和Edge等浏览器已经开始支持HTTP/3。支持可能会随着浏览器版本的更新而改变。
  • 服务器兼容性: HTTP/3的支持需要使用QUIC协议。Nginx、Apache等一些主要的Web服务器也开始提供HTTP/3支持。请确保服务器软件和配置是最新的,以支持HTTP/3。

在实际应用中,为了确保最佳的性能和兼容性,建议使用HTTPS,并在支持的情况下启用最新的HTTP协议版本。这样可以充分利用新协议的性能优势,并确保网站在各种浏览器和设备上都能够正常运行。总体而言,HTTP/2 和 HTTP/3 通过引入新的技术和特性,旨在提高网页加载性能,减小延迟,并在不同网络条件下更好地工作。HTTP/3 的引入 QUIC 协议和其他改进,使其在处理连接问题和网络中断时更加灵活和高效。选择使用哪个协议通常取决于服务器和客户端的支持情况,以及具体的性能需求。

5. 配置

要在网站中设置 HTTP/2 优先,并在不支持 HTTP/2 的情况下回退到 HTTP/1,您可以通过适当配置您的 web 服务器来实现。以下是一些常见服务器的配置示例:

Nginx 配置示例:

server {
    listen 443 ssl http2;  # 启用 HTTP/2

    # SSL 配置(确保已配置 SSL 证书等)

    # Other server configurations...

    location / {
        # Your application settings...
    }
}

server {
    listen 443 ssl fallback;  # 回退到 HTTP/1

    # SSL 配置(确保已配置 SSL 证书等)

    # Other server configurations...

    location / {
        # Your application settings...
    }
}

Apache 配置示例:

<VirtualHost *:443>
    Protocols h2 http/1.1  # 启用 HTTP/2

    # SSL 配置(确保已配置 SSL 证书等)

    # Other server configurations...

    <Location />
        # Your application settings...
    </Location>
</VirtualHost>

<VirtualHost *:443>
    Protocols http/1.1  # 回退到 HTTP/1

    # SSL 配置(确保已配置 SSL 证书等)

    # Other server configurations...

    <Location />
        # Your application settings...
    </Location>
</VirtualHost>

  • Nginx 通常支持 HTTP/1 和 HTTP/2。要启用 HTTP/3,您需要使用支持 QUIC 协议的 Nginx 版本。您可以按照官方文档的指南进行操作。
  • 在配置文件中,您可以使用以下行启用 HTTP/3:
listen 443 ssl http2;
listen [::]:443 ssl http2;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off;
ssl_certificate /path/to/certificate;
ssl_certificate_key /path/to/private/key;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;
ssl_dhparam /path/to/dhparam.pem;
ssl_stapling on;
ssl_stapling_verify on;
add_header Strict-Transport-Security max-age=15768000;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
http2_chunk_size 8k;
http2_max_concurrent_streams 64;
http2_max_field_size 16k;
http2_max_header_size 32k;
http2_max_requests 1000;
http2_recv_buffer_size 1m;
http2_send_buffer_size 1m;
http2_ssl_protocols TLSv1.2 TLSv1.3;
http2_ssl_session_timeout 10m;
http2_ssl_session_tickets off;
http2_ssl_stapling on;
http2_ssl_trusted_certificate /path/to/trusted_certificate;
http2_ssl_verify_depth 2;
http2_stream_idle_timeout 3d;
http2_push_preload on;

Apache HTTP Server:

  • Apache 支持 HTTP/1 和 HTTP/2,但要启用 HTTP/3,您需要使用支持 QUIC 协议的 Apache 版本。最好按照官方文档的指南进行操作。

Node.js (Express):

  • 对于 Node.js,您可以使用 Express 框架并确保使用的是支持 HTTP/2 的版本。
  • 在 Express 应用中,您可以通过以下方式启用 HTTP/2:
const https = require('https');
const express = require('express');
const app = express();

const server = https.createServer({
  key: ...,
  cert: ...,
  // Other options
  allowHTTP1: true, // Allow HTTP/1
  enableHttp2: true, // Enable HTTP/2
}, app);

server.listen(443);