ThinkPHP 6 强制 HTTPS 需通过 Nginx 配置 return 301 https://$host$request_uri; 实现可靠跳转;PHP 层需设 Cookie/Session 的 secure=>true、httponly=>true、samesite=>'Lax';前端资源须用 window.location.origin 或 url() 动态生成,避免混合内容。

ThinkPHP 6 如何强制 HTTPS 跳转
不配对的 HTTP/HTTPS 混合访问,会导致 Cookie 被浏览器拒绝(尤其 secure 属性开启时),Session 失效、AJAX 请求被拦截、前端获取不到 $_SERVER['HTTPS'] 正确值。ThinkPHP 本身不自动处理协议跳转,得靠 Web 服务器或中间件兜底。
推荐用 Nginx 配置跳转,比 PHP 层判断更早、更可靠:
- 在站点 server 块中加
return 301 https://$host$request_uri;,并确保只对 80 端口生效 - 避免在 PHP 中用
header('Location: https://...'),容易漏掉 POST 请求重定向、引发重复提交 - 如果必须用中间件(如测试环境无反代权限),在
app/middleware.php加一个闭包:function ($request, \Closure $next) { if (!$request->isSsl()) { return redirect()->to('https://' . $request->host() . $request->url()); } return $next($request); }
HTTPS 下 ThinkPHP 的 Cookie 和 Session 安全配置
setcookie() 和 session_set_cookie_params() 默认不设 secure 和 httponly,明文 HTTP 下也能写入,但一旦启了 HTTPS,没配 secure 就等于把 Cookie 暴露给后续可能的 HTTP 请求。
ThinkPHP 6 的 config/cache.php 和 config/session.php 必须显式声明:
立即学习“PHP免费学习笔记(深入)”;
-
'secure' => true(强制仅 HTTPS 传输) -
'httponly' => true(防 XSS 窃取) -
'samesite' => 'Strict'或'Lax'(防 CSRF,推荐Lax兼容性更好) - 注意:若部署在子路径(如
/sub/),'path'要同步设为'/sub/',否则 Cookie 不下发
前端 AJAX 在 HTTPS 环境下跨域或 Mixed Content 报错
浏览器控制台报 Mixed Content: The page at 'https://...' was loaded over HTTPS, but requested an insecure resource 'http://...' —— 这不是 ThinkPHP 的错,是前端写的 URL 写死了 http:// 或相对协议 //api.example.com 但后端实际没走 HTTPS。
解决关键在统一协议源头:
- 不要在 JS 里硬编码
http://api.example.com,改用window.location.origin + '/api/xxx' - 如果用
axios,在create时设baseURL: '/api',让所有请求走同源 - 后端接口返回的资源链接(如图片地址、跳转 URL)也要用
url()或fullUrl()生成,别拼字符串 - 检查
config/app.php中'url' => 'https://example.com'是否已设,否则url()生成的仍是 http
SSL 证书验证失败导致 curl 请求异常(如微信支付回调)
本地开发或内网部署时,用自签证书或未信任 CA,ThinkPHP 的 think\facade\Http 或第三方 SDK(如 wechatpay-php)发起 HTTPS 请求会抛出 cURL error 60: SSL certificate problem。
不能简单关掉证书验证(CURLOPT_SSL_VERIFYPEER => false),生产环境必须校验:
- 测试阶段可临时加
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false),但仅限 CLI 或非生产环境 - 正式环境要确保系统 CA 证书库更新:
sudo apt update && sudo apt install ca-certificates(Ubuntu) - 若用宝塔/Nginx,确认
ssl_trusted_certificate指向完整证书链(含中间 CA),不只是域名证书 - ThinkPHP 自带的
Http::post()不暴露 cURL 参数,需换用原生curl_init()或封装一层支持verify选项的客户端
HTTPS 不是开关一按就完事,协议层、Web 服务层、PHP 配置层、前端资源层,任何一层漏配都可能让加密变成摆设。最常被忽略的是 Cookie 的 secure 属性和前端资源链接的协议一致性。


















