FrankenPHP在CDN终止HTTPS场景下需监听HTTP端口并显式配置X-Forwarded-Proto头,同时Laravel必须启用TrustProxies中间件信任代理头,否则协议判断错误导致混合内容或重定向循环。

要重配,但只重配源站部分,CDN侧基本不动。
CDN终止HTTPS时FrankenPHP必须监听HTTP
CDN(比如 Cloudflare、阿里云全站加速)把 TLS 解密做完后,转发给源站的是明文 HTTP 请求。FrankenPHP 默认只监听 HTTPS(如果用了 Caddy 自动证书),这时会直接拒绝 HTTP 请求,返回 400 Bad Request 或连接被拒。
- 必须在
Caddyfile里显式启用 HTTP 端口,例如:{\n servers {\n listen :80\n }\n} - 不要删掉
yourdomain.com块里的php_server,它仍需处理来自 CDN 的 HTTP 请求 - 禁用 FrankenPHP 的自动 HTTPS(即不写
https://域名或不配 TLS 块),否则 Caddy 会尝试自己做 TLS,和 CDN 冲突
HTTP头传递必须补全,否则 Laravel 认不出是 HTTPS
Laravel 的 url()、secure_url()、重定向生成等逻辑依赖 $_SERVER['HTTPS'] 或 $_SERVER['HTTP_X_FORWARDED_PROTO'] 判断协议。CDN 转发 HTTP 请求时,默认不带这些头,Laravel 就会生成 http:// 链接,造成混合内容或跳转错误。
- 在
Caddyfile的站点块里加header_up X-Forwarded-Proto {http.request.header.X-Forwarded-Proto}——但更简单的是直接设死:yourdomain.com {\n header_up X-Forwarded-Proto "https"\n php_server\n} - 同时确保 Laravel 开启了信任代理:在
App\Http\Middleware\TrustProxies中设置$proxies = '*';或具体 CDN IP 段 - 漏掉这步,
route('home')可能输出http://example.com/,前端 JS 调用 API 也会走错协议
别在CDN和FrankenPHP两端都开“强制HTTPS”
Cloudflare 的「Always Use HTTPS」或阿里云的「HTTP回源自动跳转 HTTPS」一旦开启,又在 FrankenPHP 的 Caddyfile 里配了 redir https://{host}{uri} permanent,就会触发 ERR_TOO_MANY_REDIRECTS。
立即学习“PHP免费学习笔记(深入)”;
- CDN 层开「强制 HTTPS」是安全的,它只影响访客到 CDN 的链路
- FrankenPHP 源站**绝对不要配任何 301 到 HTTPS 的规则**,它只管 HTTP 回源请求
- 验证方法:用
curl -v http://yourdomain.com直连源站 IP(绕过 CDN),应返回 200,而不是 301
最容易被忽略的是 X-Forwarded-Proto 的硬编码——很多人只记得加 header_up,却忘了 Laravel 默认不信任所有代理头,没配 TrustProxies 中间件的话,那个 header 就等于没传过去。



















