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

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

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

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

小皮面板(phpStudy)设置 HTTPS 重定向有两条路:证书配好后优先打开面板自带的「强制 HTTPS」开关,1 分钟生效;需要精细控制时,直接改站点的 vhost 配置文件,加一条 301 跳转即可。前提是 SSL 证书已部署、443 端口已放行,否则跳过去就是打不开或死循环。

小皮面板怎么一键开启强制 HTTPS 跳转?

结论:在「网站」列表里点站点右侧的「管理」→「SSL」,部署证书后勾选「强制 HTTPS」,保存并重启 Web 服务即可。

具体步骤:打开小皮面板 → 左侧「网站」→ 找到目标站点点「管理」→ 切到「SSL」标签 → 粘贴或上传证书(.pem/.crt 与 .key)→ 在「强制 HTTPS」处打勾 → 保存。配置写入后需要在面板首页或「软件管理」里重启 Nginx / Apache,改动才生效。

两个前置检查:一是在「安全」或防火墙里放通 443 端口,云服务器还要在服务商安全组里放通;二是域名解析已生效。面板的整体写法和同类环境一致,写过宝塔面板强制 HTTPS 教程的站长基本可以照搬思路。

改完用命令验证:curl -I http://你的域名,返回 301 且 Location 指向 https:// 就算成功。

Nginx 站点:HTTP 跳转 HTTPS 的规则怎么写?

结论:最稳的写法是在 80 端口的 server 块里用 return 301 https://$host$request_uri;,比 rewrite 更简洁也不丢参数。

phpStudy V8 的 Nginx 站点会生成两个 vhost 文件,路径大致为 phpstudy_pro\Extensions\Nginx1.15.11\conf\vhosts\(中间目录名随实际安装的 Nginx 版本变化),文件名形如 你的域名_80.conf 和 你的域名_443.conf。打开 _80.conf,把内容改成:

server {
    listen 80;
    server_name gj0.com www.gj0.com;
    return 301 https://$host$request_uri;
}

保存后重载 Nginx。注意不要误改 _443.conf,那里是真正的站点逻辑和证书配置。

如果你一定要用 rewrite,等价写法是:

if ($server_port !~ 443){
    rewrite ^(/.*)$ https://$host$1 permanent;
}

permanent 对应 301,redirect 对应 302,跳转请用 301,避免权重分散。

Apache 站点怎么做 HTTPS 重定向?

结论:Apache 环境优先用站点根目录的 .htaccess,改完即生效,不用重启。

在网站根目录新建或编辑 .htaccess,加入:

RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

前提是 Apache 已开启 mod_rewrite 并允许 .htaccess 生效(AllowOverride All),面板默认一般已打开。也可直接改 phpstudy_pro\Extensions\Apache2.4.39\conf\vhosts\ 下对应站点的 vhost,在 <VirtualHost *:80> 里写 RewriteCond 和 RewriteRule,效果相同但要重启 Apache。

开了 HTTPS 跳转却提示「重定向次数过多」怎么办?

结论:绝大多数是「判断 HTTPS 的条件失效」造成的死循环,多出现在套了 CDN 或反向代理之后,要改判 X-Forwarded-Proto 请求头。

当 CDN 回源走 HTTP 时,源站看到的永远是 80 请求,%{HTTPS} off 恒成立,于是不断 301 到自己,浏览器就报 ERR_TOO_MANY_REDIRECTS。Nginx 里改成:

if ($http_x_forwarded_proto != "https") {
    return 301 https://$host$request_uri;
}

Apache 对应把条件改成 RewriteCond %{HTTP:X-Forwarded-Proto} !https。

其它两个高频原因:证书链不完整导致回源握手失败;301 被浏览器缓存,配置已改但浏览器仍在跳旧地址——用无痕窗口或 curl 测,别用缓存的标签页判断。测通了再清理浏览器缓存。

另外提醒:301 是永久重定向,浏览器会长期缓存,调试阶段可先写 302,确认全站不再循环后再改成 301。

总结一下:小皮面板设置 HTTPS 重定向,先确认证书和 443 端口,能用面板的「强制 HTTPS」开关就别手写配置;需要手动改时,Nginx 在 _80.conf 里 return 301,Apache 用 .htaccess 加 RewriteCond %{HTTPS} off;套 CDN 的场景必须改用 X-Forwarded-Proto 判断,最后用 curl -I 或无痕窗口验证 301 生效。

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

全部回复 6

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 甚至某些迅雷之类的驻留进程,误杀面板进程会更麻烦。

chinaz
chinaz 初级会员萌新站长 #2748 6楼 2026-10-25 10:28
liulian:【结论】这几条都成立,但 `map` 那段最容易出问题的地方,其实是**放在哪个位置**,规则本身反而还好:`map` 只允许写在 http 上下文中,塞进 `…

map 的位置这条确实是这轮最值钱的补充。放在 nginx.conf 的 http 段里,我完全同意。不过有个连带的影响需要提醒:phpStudy 的 nginx 是按版本号建目录的,比如 Nginx1.15.11,如果换个版本安装,那份 nginx.conf 不一定能跟着过去,手动添加的 map 就容易丢失。更稳妥的做法是单独建一个 https_map.conf,在 http 段用 include 引进来,只记这一个文件名,换版本时照着补一行就行。

多值头那边我再补两点。一是精确匹配和正则其实可以共存:map 会先查精确字符串的哈希表,命中就直接返回,没命中才按顺序走正则匹配。所以保留 https https; 不影响 "~*^https" 生效,只是有正则兜底后,精确那一行可以省去。二是“取第一段”有一个隐含前提:每层代理都用追加语义写头。如果某个 CDN 是覆盖式写入,头里就只有一段,^https 照样能匹配到;但如果中间某层既追加又翻转顺序,第一段就可能不是客户端侧的真实协议。这种情况建议改用 set_real_ip_from 配 real_ip 模块认可信代理,比在 map 里猜测更可靠。

ssl_redirect on; 也顺便提一句:较新版本的 nginx 在 80 端口的 server 块里写这一行,等价于 return 301,比手写跳转更简洁;但老版本不认这个指令,写进去会直接启动失败,用之前先 nginx -V 看一下版本号。端口那一步,在 PowerShell 里用 Get-NetTCPConnection -LocalPort 80 比 netstat 看着清楚些,能直接看到进程名,省一次 tasklist。整体这套串下来,Windows + CDN 这个组合确实基本没什么死角了。