微信小程序与 H5 调用第三方 API:把差异留在请求层
小程序和 H5 调用第三方 API 的可靠做法是前端不持有第三方密钥、调用统一收敛到一层请求层;两个运行时的域名与跨域限制、凭证存放、错误与重试责任都应显式定义。具体平台规则本文没有可核验材料,需对照官方文档。
- 第三方 API 密钥不进小程序包和 H5 脚本,改为经自己的后端转发,顺带获得限流、日志和可替换供应商的能力。
- 把 baseURL、超时、重试、幂等键、错误分类集中在请求层,业务代码只传参数,不各自写死。
- 写操作只有在带幂等键时才允许重试;超时后服务端可能已成功,同样按幂等处理。
微信小程序和 H5 调用第三方 API 的“正确姿势”,一句话概括:前端不持有第三方密钥,把调用收敛到一层可替换的请求层,并把两个运行时的差异显式写出来。两者都不是“拿到 URL 就发请求”那么简单,差别主要在鉴权位置、域名与跨域约束、以及错误和重试由谁负责。本文没有任何可核验的平台文档或接口材料,涉及具体平台规则、字段名和版本能力的地方一律标注待核实,实现前请对照对应平台的官方文档。
一、先确认两个运行时的差异#
同样是调用第三方 HTTP 接口,小程序和 H5 遇到的限制并不一样。下面这些是工程上需要先分清的点;具体规则以各自官方文档为准,本文不代为断言。
| 关注点 | 小程序 | H5 | 收敛方式 |
|---|---|---|---|
| 域名与协议 | 网络请求受平台域名配置约束(具体字段与是否要求 HTTPS,待核实) | 受浏览器同源策略约束,跨域需服务端返回 CORS 响应头 | 统一经自己的后端域名出网,两类限制一起绕开 |
| 凭证存放 | 代码包可被解包 | 脚本可被查看 | 第三方密钥只放服务端 |
| 登录态 | 获取方式与 H5 不同(细节待核实) | 通常依赖 Cookie 或自有 token | 请求层只依赖一个抽象的 token 提供者 |
二、密钥和鉴权放在哪#
不要在前端放第三方 API Key。哪怕是“只读”“低权限”的密钥,只要下发到客户端就等于公开。可行做法是自建或复用一层后端转发:前端带自己的会话凭证调自己的接口,后端再带第三方密钥出网,把结果裁剪后返回。这层转发同时带来可观测、可限流、可更换供应商三个好处。API.PLUS 侧的鉴权方式与密钥形态需以其接入文档为准(待核实),本文不假设具体字段名。
三、请求层要固定哪些字段#
把变化留在配置层,把不变留给调用方。建议请求层至少显式定义:baseURL、超时、重试次数与退避策略、幂等标识、错误分类,以及日志字段(请求 id、耗时、状态码)。超时和重试不要散落在各业务调用里写死,否则后期无法统一调整。
// 未执行示例:仅演示请求层结构,域名与字段均为占位
const API_BASE = 'https://example.com/api'; // 占位域名
async function request(path, { method = 'GET', body, signal, idempotencyKey } = {}) {
const res = await fetch(API_BASE + path, {
method,
headers: {
'content-type': 'application/json',
...(idempotencyKey ? { 'idempotency-key': idempotencyKey } : {}),
},
body: body ? JSON.stringify(body) : undefined,
signal,
});
if (!res.ok) throw new Error(`HTTP ${res.status}: ${await res.text()}`);
return res.json();
}
小程序端的网络 API 名称、是否支持 AbortController 以及可用的基础库版本需要核对(待核实),上面的写法不能直接照搬。这段代码没有运行过,只用于说明字段该放在哪一层。
四、错误分类与重试边界#
- 4xx 一般不要重试,408 和 429 除外;5xx 与网络错误可以做有限次重试。
- 写操作必须带幂等键才允许重试,否则可能重复创建或重复扣费。
- 遇到 429 时优先读取服务端给出的
Retry-After,不要用自己的固定退避硬顶。 - 超时只是客户端放弃等待,服务端可能已经执行成功,因此超时后的处理同样按幂等考虑。
这些是通用工程规则。具体接口是否支持幂等键、是否返回 Retry-After,需要查该接口的文档(待核实)。
五、上线前的核对清单#
- 请求域名与协议符合目标平台要求,且已在小程序侧完成配置(规则待核实)。
- 前端产物中搜不到任何第三方密钥或长期令牌。
- 超时、重试、幂等键在请求层集中定义,业务代码没有各自实现。
- 错误提示面向用户可读,日志里不出现 token 和密钥,必要时脱敏。
- 接口变更时只需改配置层,不改调用点。
说明:本文未引用外部来源,也未访问或调用任何端点。上表中的平台规则与接口能力均为待核实项,请以对应官方文档为准。