HSTS是HTTP协议层面的安全响应头机制,非HTML5特性,必须由服务器在HTTPS响应中设置Strict-Transport-Security头才能生效;<meta>标签无效,因首次HTTP请求时HTML尚未加载;正确配置需满足证书有效、仅限HTTPS响应、合理设置max-age/includeSubDomains/preload参数,并优先小范围测试。

Strict-Transport-Security(HSTS)不是HTML5的特性,而是HTTP协议层面的安全响应头机制。它不能通过HTML标签(如<meta>)真正实现“强制HTTPS访问”,也不能在页面加载后才起作用——它的生效依赖于服务器在HTTPS响应中正确返回该头部。
下面讲清楚怎么用、为什么这么用,以及常见误区:
HSTS必须由服务器在HTTPS响应中设置
浏览器只信任从合法HTTPS连接收到的Strict-Transport-Security响应头。如果网站本身没配好HTTPS,或响应头出现在HTTP响应里,该头会被完全忽略。
典型正确配置(以Nginx为例):
立即学习“前端免费学习笔记(深入)”;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
-
max-age=31536000:告诉浏览器未来1年内,对该域名及子域的所有HTTP请求自动转为HTTPS -
includeSubDomains:策略覆盖api.example.com、cdn.example.com等所有子域 -
preload:表示你已申请加入浏览器预加载列表(如Chrome、Firefox内置HSTS列表),首次访问也会强制HTTPS(需额外提交到 hstspreload.org)
⚠️ 注意:preload不可轻易启用。一旦提交并通过审核,撤回周期极长(数月甚至更久),且期间任何HTTP服务中断都会导致用户完全无法访问。
为什么不能靠<meta>标签实现HSTS
有人尝试这样写:
<meta http-equiv="Strict-Transport-Security" content="max-age=31536000">
这是无效的。RFC 6797明确规定:HSTS只能通过HTTP响应头传递,<meta>标签不被任何主流浏览器支持。原因很直接——用户第一次输入http://example.com时,浏览器发出的是明文HTTP请求,HTML还没下载,<meta>根本不存在。
它和upgrade-insecure-requests的区别
后者是CSP指令,仅在当前已是HTTPS页面时生效,作用是把页面内<img src="http://...">这类资源请求自动升级为HTTPS,不改变地址栏、不处理跳转、也不影响用户首次输入协议。
HSTS解决的是更底层的问题:
- 首次输入
example.com(无协议)→ 浏览器默认发HTTP → HSTS缓存存在 → 自动改发HTTPS - 点击第三方网站上的
http://example.com链接 → 同样被升为HTTPS - 即使证书错误(如自签名、过期),用户也无法点击“继续访问”
实际部署关键点
- 确保全站已稳定运行HTTPS(证书有效、链路完整、重定向无环)
- 先用较小
max-age(如300秒)测试,确认无子域遗漏或混合内容问题 - 检查响应头是否真实存在:用浏览器开发者工具 → Network → 切换到任意HTTPS页面 → 查看Response Headers中是否有
Strict-Transport-Security - 避免跨域场景下误触发HSTS导致CORS失败:若API网关返回了HSTS头,而前端仍用HTTP调用,浏览器会307升级协议,Origin变化引发跨域拦截
不复杂但容易忽略


















