容器与平台

微信小程序服务器域名的 HTTPS 配置

作者: · 最后核实

微信小程序只能请求满足四个条件的 HTTPS 域名:已 ICP 备案、使用受信任证书、证书链完整、支持 TLS 1.2 及以上,并且要在小程序后台配置为合法域名。示例接口域名是 api.example.com,规则以微信开放文档为准(截至 2026 年 11 月)。

前提条件

小程序对服务器域名的要求比浏览器更严格。

  • 一个已完成 ICP 备案的域名,例如 api.example.com,A 记录指向服务器,例如 203.0.113.10。
  • 服务器已能通过 HTTPS 提供接口,证书由受信任的 CA 签发(Let's Encrypt、阿里云、腾讯云免费证书均可),不能是自签名证书。
  • 小程序管理员或开发者权限,能登录微信公众平台的小程序后台。

第一步:确认证书链完整、TLS 1.2 可用

证书链缺中间证书是小程序真机报错最常见的原因,浏览器能打开不代表小程序能用。用 openssl 检查证书链和 TLS 1.2:

openssl s_client -connect api.example.com:443 -servername api.example.com -showcerts </dev/null 2>/dev/null | grep -E '^ *[0-9] s:'
openssl s_client -connect api.example.com:443 -servername api.example.com -tls1_2 </dev/null 2>/dev/null | grep -E 'Protocol|Cipher'

第一条应列出至少两张证书(深度 0 和 1);第二条应成功协商 TLSv1.2。缺中间证书的按 安装中间证书 处理。

第二步:服务器使用推荐的 TLS 配置

以 Nginx 为例,证书使用完整证书链,协议开启 TLS 1.2 和 1.3:

server {
    listen 443 ssl;
    http2 on;    # Nginx 1.25.1 及以上;更老的版本写 "listen 443 ssl http2;"
    server_name api.example.com;

    ssl_certificate     /etc/letsencrypt/live/api.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/api.example.com/privkey.pem;
    ssl_protocols       TLSv1.2 TLSv1.3;

    location / {
        proxy_pass http://127.0.0.1:3000;
    }
}

还没有证书的,按 Nginx 配置 Let's Encrypt 或 腾讯云 SSL 证书申请 申请。

第三步:在小程序后台配置服务器域名

小程序只会请求后台登记过的服务器域名。登录小程序后台,进入 开发管理 → 开发设置 → 服务器域名,点“修改”:

  • request 合法域名:https://api.example.com
  • socket 合法域名:wss://api.example.com(用 WebSocket 时)
  • uploadFile / downloadFile 合法域名:按需填写

规则要点:只能填 https/wss 域名;不能填 IP 或 localhost;配置了端口(如 https://api.example.com:8443)就只能请求这个端口;api.weixin.qq.com 不能配置为服务器域名。修改次数有限制,以后台提示为准。

第四步:真机测试

证书和域名配置要在真机上验证。开发者工具 详情 → 本地设置 里的“不校验合法域名、web-view(业务域名)、TLS 版本以及 HTTPS 证书”只用于本地调试,测试前取消勾选。然后用“真机调试”或预览二维码在 iOS 和安卓手机上各测一次,确认请求成功。

验证

配置正确时,接口域名的证书链完整,支持 TLS 1.2 和 1.3,证书没有过期。用 SSL 证书检查 检查接口域名,或在终端运行:

curl ssl.sh/api.example.com

缺中间证书时,用 证书链生成器 生成正确的证书链文件。

自动续期

续期后证书变了,但域名没变,小程序后台不需要任何修改。主要风险是证书过期:一旦过期,所有用户的接口请求都会失败,而且用户看不到任何可以跳过的提示。因此:

  • 用 Certbot、acme.sh 等客户端自动续期,并在续期后自动重载 Nginx(见 证书自动续期)。
  • 云厂商的免费证书同样受有效期上限约束(2026 年 3 月 15 日起 200 天,2029 年 3 月 15 日起 47 天),手动更换很容易遗漏。
  • 把接口域名加到 ssl.sh 监控(开发中),到期前收到提醒。

常见问题排查

  • request:fail url not in domain list:域名没有配置为合法域名,或协议、端口不一致,见常见问题。
  • request:fail ssl hand shake error:证书链不完整、TLS 版本不支持 1.2、证书过期或域名不匹配,见 缺少中间证书 和 ERR_SSL_VERSION_OR_CIPHER_MISMATCH。
  • 安卓正常、iOS 失败(或反过来):多半是证书链问题,不同系统补全中间证书的能力不同。
  • 用了自签名证书:小程序不信任自签名证书,换成受信任 CA 的证书,见 证书链中有自签名证书。
  • 证书过期导致全部请求失败:见 NET::ERR_CERT_DATE_INVALID,并补上自动续期和监控。

常见问题

可以用 Let's Encrypt 免费证书吗?

可以。小程序要求的是受信任 CA 签发的有效证书,Let's Encrypt、阿里云和腾讯云的免费证书都满足。关键是证书链要完整、TLS 1.2 以上可用,并且续期全自动,否则证书一过期接口就全部失败。

后台配置了域名,真机还是报 url not in domain list?

检查四点:协议和域名是否完全一致(https 与 wss 分开配置);请求带了端口但后台没配置该端口,或反过来;修改后需要重新进入小程序让配置生效;请求的是否是业务域名(web-view)而不是服务器域名。

web-view 打开的网页也有要求吗?

有。web-view 加载的页面域名要配置为业务域名,同样必须是备案的 HTTPS 域名,并需要按后台提示把校验文件放到网站根目录。证书要求与服务器域名相同。

资料来源

  1. 微信开放文档:小程序网络使用说明
  2. Let's Encrypt: Challenge Types
  3. nginx: Configuring HTTPS servers