html中完全无效,因rfc 6797明确禁止该用法,hsts必须通过https响应头在tls握手后注册,首次http访问时html尚未加载,策略时机已错过。

HTML里写完全无效
不能在 index.html 或任何 HTML 文件中通过 <meta http-equiv="Strict-Transport-Security"> 启用 HSTS。RFC 6797 明确禁止该用法,所有主流浏览器(Chrome、Firefox、Safari、Edge)均忽略它,连 Response Headers 面板里都看不到字段。
根本原因在于:HSTS 是 HTTP 协议层机制,必须在 TLS 握手完成后的第一个 HTTPS 响应头中注册。用户首次访问 http://example.com 时,连接是明文的,HTML 根本没开始下载,<meta> 还不存在——策略注册时机早已错过。
- 常见错误现象:
curl -I https://example.com输出里没有Strict-Transport-Security头 - DevTools Network 面板中 HTTPS 请求的 Response Headers 为空
-
chrome://net-internals/#hsts查询显示 “Not found”
Nginx 中 add_header Strict-Transport-Security 的正确位置和参数
HSTS 头必须由服务器在 HTTPS 响应中发出,且仅限 listen 443 ssl 的 server 块顶层配置,绝不能放在 location / 内或 HTTP server 块中。
关键配置示例:
server {
listen 443 ssl http2;
server_name example.com;
ssl_certificate /path/to/fullchain.pem;
ssl_certificate_key /path/to/privkey.pem;
<pre class="brush:php;toolbar:false;"># ✅ 正确:server 块顶层,带 always 参数
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
location / {
root /var/www/html;
}}
-
always参数不可省:否则304、4xx等非 200 响应不携带该头 - 不要加在
listen 80块里——HTTP 响应中的 HSTS 头会被浏览器静默丢弃 - 首次上线建议先设
max-age=300(5 分钟),验证无资源加载失败再延长
启用 preload 前必须确认三件事
preload 不是开关,而是向 hstspreload.org 提交“永久强制 HTTPS”的申请。一旦收录,新装浏览器首次访问就会跳 HTTPS,且撤回周期长达数月。
- 全站所有子域名(如
api.example.com、cdn.example.com)均已部署有效 TLS 证书并可 HTTPS 访问 -
Strict-Transport-Security响应头必须含max-age=31536000且带includeSubDomains - 测试环境、自签名证书、
localhost域名严禁提交 —— 提交后新装浏览器将永远拒绝 HTTP 访问
HSTS 生效的前提是服务端 301 重定向 + 无一遗漏的 HTTPS 资源
HSTS 本身不解决首次访问问题。用户第一次输入 example.com,浏览器默认发 HTTP 请求;若没配重定向,页面就已明文加载完毕,HSTS 头根本来不及下发。
- 必须在
listen 80的server块中配return 301 https://$host$request_uri;(不是rewrite,也不是302) - 所有子域名都要做同样重定向,不能只配
www或主域名 - 真正难的不是加那行
add_header,而是确保全站无一个http://资源——少一个图片、脚本或 iframe,HSTS 启用后用户就白屏或功能中断
HSTS 的核心陷阱不在配置语法,而在“全站 HTTPS 就绪”这个前提是否真正闭环:证书有效性、子域覆盖、重定向完整性、资源协议一致性,缺一不可。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











