输 http://yourdomain.com 站点能打开——没跳 HTTPS。Search Console 把每个 URL 的 http 和 https 都单独列。Chrome 在 http 请求显示 “Not Secure”。不强制 HTTPS 的话,对 Google 来说你有一个重复站、安全评分被降,而且现代浏览器越来越歧视未加密流量。修法是平台/CDN 层加 http → https 的 301 重定向,外加 HSTS 头把浏览器锁定到 HTTPS。
常见原因
按命中率从高到低。
1. 托管平台不自动强制
某些主机(旧 Firebase 配置、自建 Nginx、某些共享主机方案)不自动 http → https。要手动开。
怎么判断:
curl -sI "http://yourdomain.com" | head -3
返回 200 = 没重定向。应该是 301 带 Location: https://...。
2. Cloudflare 用了 “Flexible SSL” 模式
“Flexible” 在 Cloudflare 边缘终结 SSL 但跟源站用 HTTP 通讯。访客看到 HTTPS 但源站还是 HTTP——不安全,且会破坏源站的 HTTPS-only 设置。
怎么判断:Cloudflare → SSL/TLS → Overview → 模式如果是 “Flexible”,改成 “Full” 或 “Full (strict)“。
3. 没设 HSTS
哪怕有重定向,浏览器首次访问还是先试 HTTP。HSTS 告诉浏览器”这个域名永远 HTTPS”,后续访问跳过 http 那一跳。
怎么判断:curl -sI https://yourdomain.com | grep -i strict-transport-security。为空 = 没 HSTS。
4. 重定向写在 app 代码、不在平台层
你在 app 代码(Express、Astro middleware)加了重定向,但它在 app 收到请求后才触发。某些 HTTP 请求根本到不了那里(CDN 拦了、静态资源路径)。
怎么判断:某些 URL 重定向、某些不。不重定向的通常是 app 代码运行之前服务的静态资源。
5. 自建 CDN / 代理直接服务 http
源站前的 CDN 配成 http 和 https 都服务。没显式规则的话 http 就保持 http。
怎么判断:绕过 CDN(curl 源站)看源站会不会重定向。源站重定向但 CDN 不重定向 = CDN 配置问题。
6. 混合内容阻碍 HSTS
<img src="http://..."> 等混合内容会让浏览器不信 HSTS。不算严格”HTTPS 未强制”,但相关症状。
怎么判断:DevTools 控制台找 “Mixed Content” 警告。
最短修复路径
第 1 步:平台层启用 force-HTTPS
Vercel — 默认开。Domain 设置里确认。
Netlify — Site settings → Domain management → HTTPS → “Force HTTPS”。勾上。
Firebase — firebase.json:
{
"hosting": {
"redirects": [
{
"source": "**",
"destination": "https://yourdomain.com/:1",
"type": 301
}
]
}
}
或用 Firebase 内建(新项目自动强制)。
Cloudflare — SSL/TLS → Edge Certificates → “Always Use HTTPS” → 开。
第 2 步:加 HSTS header
Vercel — vercel.json:
{
"headers": [{
"source": "/(.*)",
"headers": [
{ "key": "Strict-Transport-Security", "value": "max-age=63072000; includeSubDomains; preload" }
]
}]
}
Netlify — _headers:
/*
Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
先用短 max-age(300 = 5 分钟)测,稳定后再升到 63072000(2 年)。
第 3 步:Cloudflare 用 Full (strict)
SSL/TLS → Overview → 选 “Full (strict)“。Cloudflare 到源站加密并验证源站证书。
源站证书有问题先修源站(用平台证书或 Cloudflare Origin Certificate)。
第 4 步:curl 验证
curl -sI "http://yourdomain.com" | head -5
应返回:
HTTP/1.1 301 Moved Permanently
Location: https://yourdomain.com/
HTTPS:
curl -sI "https://yourdomain.com" | grep -i strict-transport-security
应显示 HSTS 头。
第 5 步:Search Console 提交 https URL
Search Console → URL Inspection → 对重要 URL 请求收录 https 版。Google 会把 http 合并到 https 作为 canonical。
第 6 步:考虑 HSTS preload
HSTS 平稳运行几个月后,把域名提交到 HSTS preload 列表。Preload 后,所有浏览器从首次访问就强制 HTTPS,连联系你服务器之前就强制。注意:从 preload 列表移除要几周。完全确定 HTTPS 永远工作再 preload。
哪些情况可能不是你操作错了
老配置可能需要手动 toggle 强制 HTTPS。新平台(Vercel、Netlify、Cloudflare Pages)默认强制。
容易误判的情况
只设 <link rel="canonical" href="https://..."> 不能阻止 Google 收录 http 版。真正让 http 退索引的是 301 重定向。
预防建议
- 第一天就在平台层强制 HTTPS。不要不开 HTTPS 就上线。
- HTTPS 稳定 30+ 天后加 2 年 max-age 的 HSTS。
- Cloudflare 用 “Full (strict)” SSL,永远别用 “Flexible”。
- 任何基础设施变更后
curl -sI http://yourdomain.com验证仍是 301。 - 审计混合内容警告(
<img src="http://...">)并修。
FAQ
- HSTS 会阻止回滚吗? 会——这是目的。浏览器在 max-age 秒内不会试 http。升 max-age 前先测稳定。要退出 HSTS,设
max-age=0;preload 列表移除要几周。 - 需要付费 SSL 吗? 不需要——绝大多数站点 Let’s Encrypt 或平台提供的证书都够用。