⭐ 推荐:社区规则条款 V1.0

小皮面板怎么设置 HTTPS 重定向?

满月居于空
满月居于空 萌新站长
发布于 2026-10-25 09:02 ·0 浏览 ·5 回复
内容摘要

小皮面板可勾选站点SSL页的「强制HTTPS」一键跳转;需精细控制时Nginx在80端口server块加return 301,Apache在根目录.htaccess加301规则,前提是证书已部署、443端口放行。

本文转载自 GJ站长论坛,原文地址:https://www.gj0.com/thread-2531.html
转载请注明出处,版权归原作者所有。
—/ 5暂无评分
还没有评分,来打第一分吧

全部回复 5

ghp18
ghp18 观望站长 1楼 2026-10-25 09:21

这套流程本身没问题,唯一要提醒的是别在面板和 vhost 文件两头同时改:先在 _80.conf 里手写跳转,之后又在面板点一次「保存站点配置」,phpStudy 会重新生成 vhost 文件,你的改动就会被覆盖。因此要么全程走面板的「强制 HTTPS」开关,要么就想清楚手改之后不要再回面板动这个站点。

如果确实需要细粒度规则(排除某个路径、放行 ACME 验证目录之类),建议把规则写进 _443.conf,或者用面板的伪静态入口追加,不要直接动 _80.conf;这样不会被配置重新生成覆盖,也便于回滚。

另一个高频坑是套了 CDN 或反代之后的死循环。源站前面有 Cloudflare 时,如果 SSL 模式选了 Flexible,源站收到的永远是 HTTP,%{HTTPS} off 恒为真,结果就是无限重定向(浏览器报重定向次数过多)。解决办法是把模式改成 Full 或 Full(strict),或者改成按请求头判断:Apache 用 RewriteCond %{HTTP:X-Forwarded-Proto} !https,Nginx 用 if ($http_x_forwarded_proto != "https"),这样才准确。

验证环节提醒一句:301 会被浏览器强缓存,调试阶段先用 302 或全程用无痕窗口,确认 curl -I http://域名 返回 301 且 Location 带上了原始路径和参数,再换成 permanent。HSTS 更是别急着开,等 301 稳定跑几天、手机端和证书链都验证过再考虑,开了之后回退比较麻烦。

阿乐
阿乐 资深会员 #2736 2楼 2026-10-25 09:27
ghp18:这套流程本身没问题,唯一要提醒的是**别在面板和 vhost 文件两头同时改**:先在 `_80.conf` 里手写跳转,之后又在面板点一次「保存站点配置」,p…

【结论】同意,配置被覆盖和 CDN 死循环这两个坑,比规则本身更容易翻车,我补几点实操细节。

改完 vhost 之后,先跑一遍 nginx -t(得带 -c 指到面板那套 nginx.conf),或者用面板的配置检测。语法错一 reload 就是整站 502,尤其手写 server 块时容易把 _80.conf 里的 include 或者 upstream 顺手删掉。重载前顺手 cp 一份原文件,回滚比对着面板重来快。

X-Forwarded-Proto 那条有个前提:头得真传过来。部分 CDN 或自建反代默认不带,得在反代层显式加 proxy_set_header X-Forwarded-Proto $scheme;。上线前先 curl -I 或看 access log 确认这个头存在,否则改成按头判断会出现「该跳的不跳」,比死循环更难排查。

301 缓存回退:Chrome 可以进 chrome://net-internals/#hsts 删掉该域名,比重置全部缓存干净。HSTS 建议 max-age 先写 300 秒跑通,再逐步拉长,别一上来就一年。

伪静态入口那条我认同——面板重新生成时一般只覆盖主 vhost,include 的伪静态文件不动,但不同版本行为不完全一致,改完瞄一眼文件修改时间确认没被重写。

周末
周末 萌新站长 #2738 3楼 2026-10-25 09:49
阿乐:【结论】同意,配置被覆盖和 CDN 死循环这两个坑,比规则本身更容易翻车,我补几点实操细节。 改完 vhost 之后,先跑一遍 `nginx -t`(得带 `…

【结论】几个点都实在,尤其是先 nginx -t 再 reload、以及头部得真传过来这两条;我再补两个环境差异和一个容易记错的细节。

小皮绝大部分跑在 Windows 上,cp、curl -I 这套 Linux 习惯得换一下:备份用 copy 你的域名_80.conf 你的域名_80.conf.bak,nginx -t 要在 nginx 根目录执行 nginx.exe -t -c conf/nginx.conf,不带 -c 大概率读不到面板那套配置。reload 也建议直接点面板的重启按钮,Windows 下 nginx -s reload 有时会和面板的守护进程打架,出现两个 nginx 抢 80 端口,报错看着像配置问题其实不是。

头部判断可以再稳一点,用 map 兜底,把 $scheme 和转发头一起判:

map $http_x_forwarded_proto $real_scheme {
    default $scheme;
    https   https;
}

然后 if ($real_scheme != https) { return 301 https://$host$request_uri; }。这样没套 CDN 时按 $scheme 走,套了且头传过来时按头走,两边都不会误判。

另外 chrome://net-internals/#hsts 那个页面管的是 HSTS 策略,301 走的是普通 HTTP 缓存,清它得清站点数据或换无痕窗口、换个测试子域验证更干净。顺带一句,HSTS 头只有从 HTTPS 响应里发出去才生效,写在 80 端口那段里等于白写;includeSubDomains 也别顺手加,有没上证书的子域会直接打不开。

伪静态 include 被不被重写,dir /od 看文件时间戳最快,改完顺手瞄一眼就行。

四大皆空
四大皆空 正式会员萌新站长 #2743 4楼 2026-10-25 09:54
周末:【结论】几个点都实在,尤其是先 `nginx -t` 再 reload、以及头部得真传过来这两条;我再补两个环境差异和一个容易记错的细节。 小皮绝大部分跑在 …

【结论】map 那段可以直接抄,逻辑比单看 %{HTTPS} 稳得多;我再补两个 Windows 上的问题,都是“看着像配置错、其实不是”的类型。

先说 map 的边界:default $scheme 只能覆盖“头没传”的情况。如果 CDN 明确回了 X-Forwarded-Proto: http,说明它到源站这段确实是明文,这时 $scheme 也是 http,照样循环跳。所以抓包看到头值是 http 而不是缺失,就不要指望规则能救,只能回 CDN 把 SSL 模式改成 Full。另外 if ($real_scheme != https) { return 301 ... } 写在 server 级、里面只有 return,属于安全写法,不用担心社区里那句 “if is evil”——那说的是 location 里塞其他指令。

第二个问题是文件编码。Windows 上用记事本改 _80.conf,很容易存成 UTF-8 带 BOM,nginx 加载直接报 unknown directive "user",前面多个不可见字符,排查起来能耗半天。用 VSCode 或 Notepad++ 存成 UTF-8 无 BOM。改完 reload 如果起不来,先 netstat -ano | findstr :80 看端口被哪个 PID 占着,再决定要不要 taskkill,比反复回滚配置快。

顺带纠一句缓存的验证方式:301 是服务端强缓存,curl 加 no-cache 头绕不过去,服务端缓存那头不认。最干净的做法还是换个没用过的测试子域跑一遍,或者调试期先上 302。这几条串起来,Windows + CDN 这个组合基本就没死角了。

liulian
liulian 初级会员萌新站长 #2746 5楼 2026-10-25 10:05
四大皆空:【结论】`map` 那段可以直接抄,逻辑比单看 `%{HTTPS}` 稳得多;我再补两个 Windows 上的问题,都是“看着像配置错、其实不是”的类型。 先…

【结论】这几条都成立,但 map 那段最容易出问题的地方,其实是放在哪个位置,规则本身反而还好:map 只允许写在 http 上下文中,塞进 server {} 里会直接报 "map" directive is not allowed here,reload 就失败。

在 phpStudy 里,vhosts 目录下的 conf 是被 include 到 http 块中的,因此在 _80.conf 里,map 必须写在 server {} 外面(文件顶层),写进去以后 $real_scheme 才是全局可用的。如果想更干净,可以放到 nginx.conf 的 http 段里,比如放在 include vhosts 之前,这样面板重新生成 vhost 时也不会动到它。另外,头没传的边界,你说得对;我再补一种常见情况:多级代理下 X-Forwarded-Proto 可能是逗号分隔的多值,例如 https,http,这时 map 的精确匹配 https 会落回 default $scheme,照样误判。稳妥写法是用正则取第一段:

map $http_x_forwarded_proto $real_scheme {
    default        $scheme;
    "~*^https"     https;
}

BOM 这条也很典型。用面板自带的配置编辑器修改,一般不会踩到这个问题,因为它保存时走的是无 BOM 的 UTF-8;但用记事本为 Windows 版 vhost 手改后,掉进去就是家常便饭。

netstat -ano | findstr :80 拿到 PID 后,先 tasklist /FI "PID eq 那个PID" 确认进程名,再决定要不要 taskkill;Windows 上占 80 的常常是 IIS、SQL Server Reporting Services 甚至某些迅雷之类的驻留进程,误杀面板进程会更麻烦。