HTTP/2可以毫无困难地通过代理,因为它运行在TCP之上,而TCP正是CONNECT隧道或SOCKS5连接所承载的。HTTP/3则不然:它运行在基于UDP的QUIC上,普通HTTP代理根本无法隧道传输UDP,而大多数SOCKS5部署也不支持。实际结果是,代理客户端几乎总是通过HTTP/2(或HTTP/1.1)与网站通信,即使网站支持HTTP/3——浏览器会静默回退。这对大多数工作来说没问题,但它改变了目标服务器看到的内容,值得理解而不是事后才发现。

三种协议一分钟速览

  • HTTP/1.1(1997年):基于文本,每个连接一次只能处理一个请求;浏览器通过并行打开多个连接来弥补。
  • HTTP/2(2015年):二进制分帧,多个并发流在一个TCP连接上多路复用,头部压缩(HPACK),服务器推送(现已基本弃用)。底层与HTTP/1.1相同,都是TCP + TLS。
  • HTTP/3(2022年):语义与HTTP/2相同,但由QUIC承载,这是一种基于UDP的传输协议,将TLS 1.3内置于握手过程中,避免了TCP队头阻塞,并允许连接在IP地址变化时存活(例如手机从Wi-Fi切换到4G)。

浏览器通过两种方式得知网站支持HTTP/3:先前HTTP/2响应中的Alt-Svc: h3=":443"响应头,或DNS HTTPS记录。一旦得知,它会在下一次连接时尝试QUIC,并记住结果。

代理如何承载每种协议

HTTP代理

对于HTTPS目标,客户端发送CONNECT host:443,代理打开到目标的TCP连接,并变成哑字节管道。客户端和目标在该管道内协商的任何内容——TLS 1.3,然后通过ALPN协商HTTP/1.1或HTTP/2——对代理不可见,并且正常工作。因此,HTTP/2通过HTTP代理是完全正常的。

UDP在这种模型中无立足之地。CONNECT创建的是TCP隧道;没有标准方法让普通HTTP/1.1代理说“将我的UDP数据报转发到此主机”。配置了HTTP代理的浏览器根本不会尝试向源服务器发起QUIC——Chrome和Firefox会为代理连接禁用HTTP/3——而是通过隧道使用HTTP/2。没有错误,没有警告。

SOCKS5代理

SOCKS5 确实定义了UDP ASSOCIATE命令用于中继数据报。原则上,SOCKS5代理可以承载QUIC。实际上:

  • 许多商业SOCKS5代理只实现CONNECT(TCP),拒绝或忽略UDP ASSOCIATE;
  • 通过SOCKS5进行UDP中继要求代理具有可达的UDP端口,并且客户端支持关联握手,而浏览器不会为HTTP/3这样做;
  • Chrome和Firefox将SOCKS代理与HTTP代理同等对待:不会尝试HTTP/3。

因此,即使代理可以转发UDP,浏览器也不会要求它。命令行QUIC客户端和一些库可以指向支持UDP的SOCKS5代理,但那是专业配置,不是默认情况。我们的SOCKS5与HTTP代理对比更广泛地涵盖了TCP/UDP区别。

什么能承载HTTP/3:MASQUE和CONNECT-UDP

IETF的MASQUE工作组标准化了CONNECT-UDP(RFC 9298),这是一个扩展,允许HTTP/3(或HTTP/2)代理隧道传输UDP负载——进而将QUIC隧道传输到源服务器。Apple的iCloud Private Relay和一些较新的隐私代理使用它。在通用商业代理和浏览器代理设置中,支持仍然不常见;当提供商宣传“HTTP/3支持”时,值得询问他们是指代理对您说HTTP/3,还是能够隧道传输HTTP/3到源服务器——这是两回事。

实际发生的情况,逐步说明

  1. 您的代理浏览器请求https://example.com。它通过代理打开CONNECT example.com:443。
  2. 在隧道内,它进行TLS 1.3握手,提供ALPN h2和http/1.1。源服务器选择h2。您使用的是HTTP/2。
  3. 响应携带Alt-Svc: h3=":443"。浏览器注意到它——并且,由于配置了代理,在连接目的上忽略它。
  4. 对该源服务器的每个后续请求都继续通过隧道使用HTTP/2。

关闭代理并重新加载:浏览器现在遵循Alt-Svc,同一站点通过HTTP/3提供服务。两种情况都没有问题;只是协议不同。

为什么这很重要

性能

HTTP/3的优势——更快的握手、在有损链路上无队头阻塞、连接迁移——在通过代理时会丢失。对于良好链路上的数据中心代理,差异很小。对于移动代理,最后一跳是有损蜂窝链路,QUIC本应最有帮助,但恰恰是您无法使用它的地方。请预算比直接HTTP/3连接稍多的延迟;参见如何测量代理速度中的方法。

指纹识别和一致性

这是微妙的一点。反机器人系统记录客户端使用的协议及其HTTP/2 SETTINGS(参见反机器人系统如何工作)。现代Chrome在直接连接时,大多数大型网站都通过HTTP/3访问。同一个Chrome通过代理时,则通过HTTP/2到达。这本身并不可疑——许多真实用户位于企业代理后面,从不使用HTTP/3——但它多了一个数据点,并且意味着您的HTTP/2指纹(SETTINGS值、头部顺序)现在总是暴露,必须与声称的浏览器一致。模拟浏览器的HTTP客户端必须模拟HTTP/2层,而不仅仅是TLS层,原因正是如此;TLS指纹识别文章解释了整个栈。

爬虫工具

Python的requests只支持HTTP/1.1;httpx可以通过h2额外支持HTTP/2;aiohttp是HTTP/1.1。没有一个能通过代理使用HTTP/3。由于代理浏览器无论如何都在HTTP/2上,因此在客户端中使用HTTP/2(如果库支持)可以让您最接近真实代理用户的样子。示例见Python中的代理。

实用指南

情况您得到的结果操作
浏览器 + HTTP代理,HTTP/3网站通过CONNECT隧道使用HTTP/2无需操作;这是正常的
浏览器 + SOCKS5代理,HTTP/3网站HTTP/2(浏览器不会通过SOCKS尝试QUIC)无需操作
您需要通过代理向源服务器使用HTTP/3需要端到端支持CONNECT-UDP/MASQUE明确询问提供商;除非确认,否则假设不支持
网站通过代理与直接访问行为不同可能与协议有关,更可能与IP有关在归咎于HTTP/3之前,先与同一代理上的真实浏览器比较
为受保护网站模拟客户端必须匹配浏览器的HTTP/2 SETTINGS和头部顺序使用模拟HTTP/2的客户端,而不仅仅是TLS
测量代理延迟同类比较:HTTP/2直连 vs HTTP/2代理不要将HTTP/3直连与HTTP/2代理比较

常见问题

HTTP/2能通过代理工作吗?

能。HTTP/2运行在TCP和TLS之上,CONNECT隧道或SOCKS5连接可以透明地承载。代理根本不需要理解HTTP/2。

HTTP/3能通过代理工作吗?

通常不能。HTTP/3使用基于UDP的QUIC;HTTP代理无法隧道传输UDP,浏览器在配置代理时不会尝试QUIC。浏览器会自动回退到HTTP/2。只有支持CONNECT-UDP(MASQUE)的代理才能将HTTP/3隧道传输到源服务器,而这很罕见。

SOCKS5代理能承载QUIC吗?

协议有UDP中继命令,但许多商业SOCKS5服务不实现它,浏览器也不将其用于HTTP/3。如果代理真正支持UDP ASSOCIATE,专业客户端可以使用。

使用HTTP/2而不是HTTP/3会被检测到吗?

本身不会——许多合法用户位于强制HTTP/2的代理后面。但这意味着您的HTTP/2指纹始终可见,因此必须与您声称的浏览器一致。

通过代理使用HTTP/3更快吗?

普通代理无法提供HTTP/3,所以问题不存在;您得到的是HTTP/2,在有损链路上比HTTP/3稍慢。在良好的数据中心链路上,差异可以忽略不计。

什么是Alt-Svc?

这是一个HTTP响应头,网站通过它告诉客户端同一资源可通过另一种协议或端口获得——通常是h3=":443"来宣传HTTP/3。浏览器在直接连接时遵循它,在配置代理时忽略它用于连接目的。