http/3 是否生效的唯一可靠判断依据是 curl --http3 -i 命令返回的 alt-svc 响应头;需确保 curl 版本≥7.64.0 且支持 http3,caddyfile 中显式启用 http3 指令,并直连后端验证。

curl --http3 命令返回 alt-svc 头才说明 HTTP/3 生效
仅靠浏览器地址栏显示「锁图标」或「https」完全不能判断是否用了 HTTP/3。FrankenPHP 启用 HTTP/3 后,服务端必须通过 alt-svc 响应头主动声明支持,客户端(如 curl)才会尝试升级。否则就是纯 HTTPS + HTTP/1.1 或 HTTP/2。
实操建议:
- 确保你用的是支持 HTTP/3 的 curl 版本(≥ v7.64.0,且编译时启用了
nghttp3和quiche);运行curl --version查看输出中是否有HTTP3字样 - 执行命令:
curl -I https://yourdomain.com --http3,注意必须加--http3参数,否则默认不走 HTTP/3 - 检查响应头里是否包含类似
alt-svc: h3=":443"; ma=86400的字段——这是唯一可信的 HTTP/3 就绪信号 - 如果报错
Unsupported protocol,说明本地 curl 不支持 HTTP/3;如果返回 404 或超时,先确认域名 DNS 解析、TLS 证书有效、Caddy 配置已启用http3
Caddyfile 中必须显式开启 http3 指令
FrankenPHP 自身不直接处理 HTTP/3,它依赖底层 Caddy Server。即使你用了 FrankenPHP 官方镜像,若 Caddy 配置没开 HTTP/3,请求永远降级到 HTTP/2。
检查你的 Caddyfile 是否包含以下任一写法:
-
https://yourdomain.com { http3 on }(全局启用) -
{ http3 on }(在全局块中启用,影响所有站点) - 没有
http3 off或被注释掉的禁用项
常见错误:只配了 tls internal 或自动证书,但漏掉 http3 指令;或者把 http3 写在了错误的作用域(比如只放在某个路由块内,而未覆盖主域名监听)。
浏览器开发者工具里看不到 HTTP/3 协议名是正常现象
Chrome 和 Edge 的 Network 面板在「Protocol」列显示 h3 的前提是:页面资源由浏览器自主发起(如 HTML、JS、CSS),且服务器正确返回了 alt-svc 头。但 FrankenPHP 的 PHP 请求处理链路中,若中间有反向代理、CDN 或负载均衡层,它们很可能剥离或忽略 alt-svc,导致浏览器收不到升级提示。
所以不要依赖 DevTools 判断,而应:
- 用
curl --http3 -I直连后端服务 IP 或容器内网地址(绕过 CDN) - 确认请求路径不是被 Caddy 重写或代理到其他服务(例如转发给 Nginx),因为只有 Caddy 原生 listener 才能发
alt-svc - 查看 Caddy 日志:
curl请求发出后,日志中出现http3: accepted connection才是真正协商成功
worker 模式下 HTTP/3 支持不受影响,但别混淆协议层和应用层
FrankenPHP 的 worker 模式提升的是 PHP 请求处理并发能力,和 HTTP/3 是正交关系——HTTP/3 在 TCP/UDP 之上完成连接协商与帧传输,worker 模式在 HTTP 请求解析之后才介入。所以无论你用普通模式还是 worker 模式,只要 Caddy 配置正确,HTTP/3 都能生效。
容易被忽略的一点是:frankenphp_handle_request() 函数本身不感知 HTTP/3,它只接收 Caddy 已解包的请求上下文。也就是说,你无需修改 PHP 入口逻辑来“适配” HTTP/3,但也不能靠它来验证 HTTP/3 是否启用。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











