xampp 8.0+默认支持openssl并启用mod_ssl和mod_rewrite;旧版本需升级或手动配置。用自带openssl.exe生成自签名证书,配置httpd-ssl.conf并添加重定向规则实现http强制跳转https,最后将server.crt导入系统受信任根证书存储以消除浏览器警告。

确认 XAMPP 版本是否支持 OpenSSL
较老的 XAMPP(如 5.6.x 或更早)默认不启用 mod_ssl,且 Apache 编译时可能未包含 OpenSSL 支持。先检查你的版本:打开 XAMPP Control Panel → 点击 Apache 右侧的 Config → 选择 Apache (httpd.conf),搜索 LoadModule ssl_module。如果这一行被注释(开头有 #)或根本不存在,说明模块未加载或不可用。
推荐使用 XAMPP 8.0+(含 Apache 2.4.52+),它默认启用 mod_ssl 和 mod_rewrite,且自带 openssl.exe 工具。旧版本升级成本高于手动编译模块,直接换新版更省事。
生成自签名 SSL 证书并配置 httpd-ssl.conf
Windows 下最稳妥的方式是用 XAMPP 自带的 openssl.exe 生成证书,路径通常为 C:\xampp\apache\bin\openssl.exe。不要用第三方工具生成 PEM 格式不兼容的密钥,否则 Apache 启动会报 SSL Library Error: error:0B080074:x509 certificate routines:X509_check_private_key:key values mismatch。
执行以下命令(在管理员权限的 CMD 中运行):
cd C:\xampp\apache\bin openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout C:\xampp\apache\conf\ssl.key\server.key -out C:\xampp\apache\conf\ssl.crt\server.crt
注意几个关键点:
-
-nodes表示不加密私钥(Apache 启动时不交互输密码,否则无法自动启动) - 输出路径必须与
httpd-ssl.conf中配置的路径一致;XAMPP 默认已预设为conf/ssl.key/server.key和conf/ssl.crt/server.crt - 填写 Common Name 时,务必填你实际访问的域名(如
localhost或test.local),浏览器会校验该字段
启用 HTTPS 并重定向 HTTP 流量到 HTTPS
仅配置 SSL 不等于强制 HTTPS —— 用户仍可通过 http://localhost 访问。要实现强制跳转,需两步:启用 mod_rewrite,并在虚拟主机中写重定向规则。
编辑 C:\xampp\apache\conf\extra\httpd-ssl.conf,找到 <virtualhost _default_:443></virtualhost> 块,在 DocumentRoot 下方添加:
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
同时确保 httpd.conf 中这行未被注释:LoadModule rewrite_module modules/mod_rewrite.so。若已启用但重定向无效,常见原因是 AllowOverride None 拦截了 .htaccess 规则——但这里我们直接写在主配置里,绕过该限制,更可靠。
验证配置并处理浏览器警告
重启 Apache 后,访问 https://localhost。若看到 “Your connection is not private” 警告,这是正常现象:自签名证书不被系统信任。不要点“高级”→“继续前往”,而应手动将 server.crt 导入系统根证书存储(Windows):
- 双击
C:\xampp\apache\conf\ssl.crt\server.crt - 选“安装证书” → “本地计算机” → “将所有证书放入下列存储” → 点“浏览”选“受信任的根证书颁发机构”
- 完成后再刷新页面,警告消失,地址栏出现锁图标
如果仍无法访问 HTTPS,检查 Windows 防火墙是否阻止了 443 端口,或是否有其他软件(如 Skype)占用了该端口 —— XAMPP 默认监听 443,冲突时 Apache 会启动失败且日志中提示 (OS 10013)An attempt was made to access a socket in a way forbidden by its access permissions。











