HSTS 必须在 HTTPS server 块中通过 add_header Strict-Transport-Security 配置并加 always 参数,且需配合 HTTP 301 重定向至 HTTPS,否则浏览器无法接收或缓存该头。

Vue 项目通过 Nginx 部署时,默认不启用 HTTPS 强制策略和 HTTP 严格传输安全(HSTS),这会让浏览器仍允许用户通过 HTTP 访问,存在降级攻击风险。要真正启用 HSTS,不能只靠 add_header,还需确保站点已正确配置 HTTPS、且响应首次来自安全连接。
为什么 add_header Strict-Transport-Security 不一定生效
HSTS 头必须通过 HTTPS 响应发送,且浏览器仅在收到该头后才开始强制后续请求走 HTTPS。如果 Nginx 同时监听 HTTP 和 HTTPS,但未重定向或未在 HTTPS server 块中配置 HSTS,则:
- HTTP 请求不会返回 HSTS 头(即使你写了
add_header,Nginx 也不允许在非 HTTPS 上下文发 HSTS) - 用户首次用 HTTP 打开页面,浏览器没收到 HSTS,后续仍可能走 HTTP
- 若 HTTPS server 块中漏配
add_header,或用了always参数不当,也可能被忽略
正确配置 HSTS 的 Nginx 片段
以下为推荐的 HTTPS server 块配置(假设已配置好 SSL 证书):
server {
listen 443 ssl http2;
server_name example.com;
<pre class="brush:php;toolbar:false;">ssl_certificate /path/to/fullchain.pem;
ssl_certificate_key /path/to/privkey.pem;
root /var/www/my-vue-app/dist;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
# ✅ 关键:在 HTTPS server 中添加 HSTS 头
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
}
注意:
-
always参数必须加上,否则 Nginx 在 304 或错误响应中不发送该头,而浏览器要求所有 HTTPS 响应(包括 200、304、404)都应携带 HSTS 才能持续生效 -
max-age=31536000表示一年,是常用保守值;上线初期可先设为300(5 分钟)测试 -
includeSubDomains表示对所有子域名生效,确认子域也支持 HTTPS 再启用 -
preload是可选标记,用于提交到浏览器 HSTS Preload List,需确保全站永久 HTTPS 且无 HTTP 回退
务必配合 HTTP → HTTPS 重定向
仅加 HSTS 不够,必须让所有 HTTP 请求跳转到 HTTPS,否则用户仍可能手动输入 http://:
server {
listen 80;
server_name example.com;
return 301 https://$server_name$request_uri;
}
这样可确保用户首次访问即走 HTTPS,顺利接收 HSTS 头。不建议用 rewrite,return 301 更高效、语义更明确。
验证与调试建议
部署后可通过以下方式确认 HSTS 是否生效:
- 浏览器开发者工具 → Network → 刷新页面 → 查看任意 HTTPS 响应的 Response Headers,确认存在
Strict-Transport-Security - 访问 hstspreload.org 检查是否符合预加载条件(如含
preload、max-age ≥ 31536000、有有效证书等) - Chrome 地址栏输入
chrome://net-internals/#hsts,查询域名是否已被记录,或手动添加测试 - 首次用 HTTP 访问会 301 跳转,第二次起即使手动输
http://,Chrome 也会自动改写为https://(前提是 HSTS 已缓存)
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










