核心是用map指令在http块定义$skip_https_redirect变量,默认1(跳转),白名单域名或IP正则匹配设为0;80端口server中if判断该变量为1时return 301跳转HTTPS,否则走后续location。

要让某些特定域名或 IP 地址访问时跳过 HTTPS 强制重定向,核心是用 map 指令提前标记“是否需要跳转”,再在 80 端口的 server 块中统一判断执行 return 301。这不是靠 location 或 if 嵌套实现的,而是通过变量驱动、逻辑清晰、性能稳定的方案。
针对特定域名跳过 HTTPS 跳转
适用于内部管理域名(如 admin.example.com)、测试子域(如 dev.example.com)等不强制走 HTTPS 的场景。关键是在 http 块中把域名映射为一个布尔型开关变量:
- 在
http{}块顶部定义map $host $skip_https_redirect - 用
default 1表示默认要跳转;对需豁免的域名设值为0 - 支持精确匹配(
admin.example.com)、通配符(*.test.example.com)和正则(~*^dev-)
示例配置:
http {
map $host $skip_https_redirect {
default 1;
admin.example.com 0;
dev.example.com 0;
~*^staging\. 0;
}
}
针对特定 IP 段跳过 HTTPS 跳转
常见于内网调试、运维监控、CI/CD 流水线调用等场景。利用 $remote_addr 匹配客户端真实 IP,避免误放行代理后的真实用户流量:
- 正则需转义点号,并用
^锚定开头(如~^192\.168\.) - 建议按 CIDR 拆分为多行正则,比单条长正则更易读、更可靠
- 若使用了反向代理(如 CDN 或 LB),需先配置
set_real_ip_from和real_ip_header,确保$remote_addr是真实客户端 IP
示例配置:
http {
map $remote_addr $skip_https_redirect {
default 1;
~^10\. 0;
~^172\.16\. 0;
~^192\.168\. 0;
127.0.0.1 0;
}
}
在 80 端口 server 中统一启用跳转逻辑
定义好变量后,在监听 80 的 server 块里只需一行判断即可完成分流:
- 用
if ($skip_https_redirect = 1) { return 301 https://$host$request_uri; } - 不需要
else分支——值为 0 的请求会自然落入后续location处理,比如直接提供 HTTP 服务或转发给后端 - 务必确保该
if在location外层,否则可能被绕过
完整片段示意:
server {
listen 80;
server_name example.com www.example.com;
<pre class="brush:php;toolbar:false;">if ($skip_https_redirect = 1) {
return 301 https://$host$request_uri;
}
location / {
proxy_pass http://backend;
# 其他代理配置
}
}
注意事项与避坑点
实际部署时容易忽略几个关键细节:
-
map必须写在http{}块内,不能放在server或location中,否则报错 - 所有匹配规则按自上而下顺序检查,但
default不参与顺序匹配,它只兜底未被任何规则捕获的情况 - 若同时有域名和 IP 双重豁免需求,可定义两个独立变量(如
$skip_by_host和$skip_by_ip),再用map合并:map "$skip_by_host:$skip_by_ip" $skip_all { "0:1" 0; "1:0" 0; "0:0" 0; default 1; } - 测试时用
curl -v http://example.com --resolve绕过 DNS,直连目标 IP,避免本地 hosts 干扰判断











