hsts本身不执行http跳转,仅在https响应中通过strict-transport-security头强制后续访问走https;真正负责跳转的是服务器配置的301重定向,需先确保http请求能正确跳转至https,再验证https响应是否携带有效hsts头。

这个问题的关键在于:HSTS 本身不参与 HTTP 到 HTTPS 的跳转,它只在浏览器已访问过 HTTPS 后才起作用。所谓“HSTS 导致跳转未生效”,通常是误解——真正负责跳转的是 return 301 或 rewrite 指令;而 HSTS 是后续阶段的强制策略。排查要分清两个独立环节:一是 HTTP 是否真能跳转到 HTTPS,二是跳转成功后 HSTS 是否被正确接收并缓存。
确认 HTTP → HTTPS 跳转本身是否工作
这是最前置、最容易被忽略的一环。如果连 301 都没发出去,就谈不上 HSTS。
- 用
curl -I http://your-domain.com查看响应状态码和Location头,必须返回301 Moved Permanently且含https://地址 - 检查 Nginx 的 80 端口 server 块:确保有
return 301 https://$host$request_uri;(推荐)或等效 rewrite 规则 - 运行
nginx -t验证语法,再systemctl reload nginx生效;注意是否有其他监听 80 的 server 块(如默认虚拟主机)造成冲突 - 用
netstat -tuln | grep :80确认 Nginx 真正在监听 80 端口,且防火墙(ufw/firewalld)已放行
验证 HTTPS 响应头中是否包含 HSTS
HSTS 头只应在 HTTPS 请求的响应中出现,且仅对 2xx/3xx 响应有效(加 always 参数可覆盖)。
- 执行
curl -I https://your-domain.com,检查输出里是否有Strict-Transport-Security:行 - 若没有,检查 HTTPS server 块中是否漏掉
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; - 注意:该指令不能写在
location块内(除非明确需要局部控制),应放在server或http块下 - 若使用 Nginx Proxy Manager 或 Ingress Controller,需确认其 UI/配置中未禁用 HSTS,或注解(如
nginx.ingress.kubernetes.io/hsts: "true")已启用
检查浏览器是否已缓存 HSTS 策略
一旦 HSTS 生效,浏览器会主动拦截所有 HTTP 请求——你根本看不到跳转过程,地址栏甚至卡在 http:// 不动,Nginx 日志里也查不到任何 80 端口访问记录。
- 在 Chrome 或 Edge 中访问
chrome://net-internals/#hsts - 在 “Query domain” 输入你的完整域名(如
test.example.com),点击 Query - 若显示 Found,说明浏览器已强制 HTTPS;此时任何 HTTP 访问都不会发出请求,自然无法触发跳转逻辑
- 若只是想临时调试,可在同一页面的 “Delete domain security policies” 区域输入域名并点击 Delete 清除本地策略
警惕预加载(preload)带来的长期影响
如果域名曾提交至 hstspreload.org 并被收录,所有主流浏览器启动时都会硬性强制 HTTPS,客户端清除无效。
- 访问 hstspreload.org 查询页,输入域名确认是否在预加载列表中
- 若已在列表中,无法通过配置或清理解除;只能等待官方更新(周期数周至数月)
- 调试建议:改用未预加载的子域名(如
dev.your-domain.com)做测试,避免干扰











