最高效安全的HTTP→HTTPS跳转方案是:在server块顶层用return 301配合HSTS,避免rewrite和location嵌套;return无正则开销,$request_uri保留查询参数,HSTS需在HTTPS server中启用且含always、includeSubDomains等参数。

直接用 return 301 实现 HTTP → HTTPS 跳转,配合 HSTS 响应头,并把逻辑放在 server 块顶层,是最高效、最安全的做法。它不依赖正则匹配,不触发 location 查找,也不产生链式跳转。
用 return 301 替代 rewrite
rewrite 指令会加载 PCRE 正则引擎,哪怕写成 rewrite ^(.*)$ https://$host$1 permanent,也会执行匹配流程;而 return 是纯指令跳转,无编译开销、无运行时判断,性能更高、更稳定。
- 正确写法:
return 301 https://$host$request_uri; -
$request_uri包含完整路径和查询参数(如/a/b?x=1),比$uri更可靠 - 结尾不加
?,除非你明确要丢弃 query string;加?可能破坏前端路由中的 hash 或参数
把重定向逻辑放到 server 块最上方
越早触发重定向,就越能跳过 root 解析、location 匹配、缓存检查等后续环节,降低延迟。
- 写在
listen 80和server_name之后、任何 location 之前 - 避免嵌套在 location 中,否则可能被其他规则覆盖或延迟执行
- server 级别的 if 是安全的,可用于协议判断,例如:
if ($scheme = http) { return 301 https://$host$request_uri; }
用 map 预计算多路径跳转(适合固定映射)
当存在大量静态路径重定向(如 /old → /new),用 map 在配置加载阶段完成映射,查询为 O(1),远快于运行时 if + rewrite。
- 在 http 块中定义:
map $uri $redirect_to { /old /new; /blog /articles; default ""; } - 在 server 中使用:
if ($redirect_to) { return 301 $redirect_to; } - 不要在 map 中用正则或动态变量,保持静态以保障性能和可预测性
HSTS 必须在 HTTPS server 块中启用
HSTS 不是可选功能,而是让浏览器“记住只走 HTTPS”的关键机制。仅靠 301 跳转无法防止首次明文请求被劫持。
- 在 443 端口的 server 块中添加:
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always; -
always参数确保 304、404、500 等状态码也携带该头 -
includeSubDomains表示策略适用于所有一级子域,启用前需确认所有子域已支持 HTTPS -
preload仅在长期稳定且已提交至 hstspreload.org 后加入,否则无法生效
避免多重跳转与 Host 头注入风险
HTTP → HTTPS → www → HTTPS+www 这类链式跳转会放大延迟,尤其影响移动端首屏加载;同时,拼接用户可控的 $http_host 可能导致跳转到恶意域名。
- 统一处理:用单条 return 实现一步到位,例如强制带 www 的 HTTPS:
return 301 https://www.$host$request_uri; - 用
$host而非$http_host,并配合严格的server_name白名单(如server_name example.com www.example.com;) - 上线前用
curl -I http://example.com检查跳转是否直达目标 URL,再用curl -I https://example.com确认 HSTS 头存在且值合理



















