用户登录

技术文章

外部链接将在新标签页打开。

微信小程序与 H5 调用第三方 API:密钥、域名与错误边界该放在哪一层

一句话回答

客户端不应直接持有第三方 API 密钥,推荐由自有后端做转发与鉴权;小程序与 H5 的差异集中在请求域名配置和跨域机制上,调用逻辑本身可以共用一套契约。本文只给出与平台无关的结构建议,未提供平台文档素材,具体限制需按各平台当前文档核实。

如果只用一句话回答:客户端只调用你自己的后端,第三方 API 的密钥、域名和重试策略都留在服务端;小程序与 H5 的差别主要在请求配置与跨域机制,而不在调用逻辑本身。本次没有可用的平台文档素材,下面给出的是与平台无关的结构建议,凡涉及具体平台限制的条目,都需要按对应平台当前版本的文档核实。

直连第三方 API 会暴露什么#

把第三方接口地址和密钥写进小程序包或 H5 前端代码,问题不在于“会不会被发现”,而在于它在前端等于公开:小程序包可分发给任意用户,H5 的脚本对访问者可见。随之而来的是几个结构性后果:

  • 密钥不可撤销地扩散。一旦泄露,只能吊销重发,而重发又要重新发版。
  • 配额无法按用户区分。所有用户共享同一个密钥额度,限流失效,也无法定位是谁在消耗。
  • 错误与重试不可控。第三方返回的错误体可能带内部字段,原样透传到终端等于把上游信息暴露给用户。
  • 平台配置成为硬约束。小程序的请求域名通常需要在后台预先配置,H5 则受浏览器同源策略约束,两者都无法靠改一行 URL 绕过。

推荐的结构:客户端 → 自有后端 → 第三方#

把第三方调用收敛到一个转发层(常见叫法是 BFF,Backend for Frontend,即面向前端聚合的后端),客户端只认自己的域名。转发层至少要承担这些职责:

  • 保管密钥,且只从服务端环境变量读取;
  • 校验调用方身份,把“谁的请求”变成可记录的事实;
  • 对入参做白名单校验,不让客户端自由拼接上游路径;
  • 设置超时、决定是否重试,并区分“可重试”与“不可重试”的错误;
  • 把第三方错误码映射成自己的稳定错误码,只回传必要信息;
  • 记录请求标识与用量,便于对账与排查。

客户端的最小封装#

下面是一段 H5 侧的请求封装,未执行示例,仅示意超时与错误分类的写法,不涉及任何真实端点:

// 未执行示例:H5 侧统一请求封装,实际运行前需按项目规范调整
async function callBackend(path, payload, timeoutMs = 8000) {
  const controller = new AbortController();
  const timer = setTimeout(() => controller.abort(), timeoutMs);
  try {
    const res = await fetch(`/api/${path}`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(payload),
      signal: controller.signal
    });
    const data = await res.json().catch(() => null);
    if (!res.ok) {
      // 只使用后端定义的错误码,不解析上游原文
      return { ok: false, code: data?.code ?? `http_${res.status}` };
    }
    return { ok: true, data };
  } catch (e) {
    // 超时与网络失败在这里合并处理,是否重试由调用方决定
    return { ok: false, code: e.name === 'AbortError' ? 'timeout' : 'network' };
  } finally {
    clearTimeout(timer);
  }
}

小程序侧的请求方法名称和参数形态与浏览器不同,但封装思路一致:统一超时、统一错误码、统一取消。小程序环境没有 DOM,也不应假设浏览器特有的 API 可用。

跨域与域名白名单是两套机制#

这是最容易把 H5 经验直接套到小程序上而出错的地方:

  • H5 受同源策略约束,跨域请求由服务端返回 CORS 响应头放行。按 CORS 规范的一般要求,携带凭证的请求不能配通配符 *,需要回显具体的来源并允许凭证;带自定义头的请求会先发 OPTIONS 预检。具体字段以 WHATWG Fetch 规范当前版本为准(本次未核验)。
  • 小程序 的请求域名通常要在管理后台登记后才可访问,登记规则、协议要求与数量上限属于平台策略,待核实,请以对应平台文档为准。

一个实用推论:如果第三方域名没有登记,或对方不提供 CORS 头,那么“前端直连”这条路在工程上就走不通,转发层不是可选项而是前提。

错误处理与可观测性#

建议把失败分成四类并分别处理:鉴权失败(密钥或用户态问题)、参数错误(重试无意义)、上游限流(按退避重试,且要有上限)、超时与网络失败(可重试但需防雪崩)。转发层向上游发请求时带上请求标识,并在返回给客户端时保留同一标识,这样用户报错时可以直接定位到一次上游调用。第三方返回的原始错误体不建议原样透传。

接入前的核对清单#

  1. 密钥是否只存在于服务端,且不写入任何前端构建产物?
  2. 客户端是否只请求自有域名?涉及平台域名登记的部分是否已按当前文档确认?
  3. 转发层是否限制了可转发的上游路径与参数,而不是通用代理?
  4. 超时、重试次数与退避策略是否明确写在配置里,而非散落在调用点?
  5. 错误码是否由自己的后端定义,并有唯一请求标识可回溯?

本文的范围限于结构层建议:没有平台文档素材,因此不对任何平台的具体规则、配额或最新政策作出判断。落地前请以对应平台官方文档与服务提供方的接口说明为准。

作者:沐小悠

本文约 7 分钟读完 · 关键词:微信小程序调用API、H5跨域请求、第三方API接入、API密钥安全、BFF转发层

更多文章 GET 示例接口

「」标签下的其他文章