# 小程序手动接入安全网关
一般情况下,推荐使用「一键接入」,支持各种灰度、一键断连、预热等配置下发,更灵活安全。但在某些特殊场景(如 PC端、Web、需要兼容低版本时)下,可以使用如下的手动接入方案。
重要:需要在 微信公众平台 中将网关域名(a****-********.sh.wxcloudrun.com) 手动加入到 request 合法域名中。
# 低版本覆盖(无框架)
- 在 app.json 中,添加使用 cloud: true 能力覆盖低版本基础库,具体操作如下:
// app.json,如果是 uniapp 在 manifest.json 中 mp-weixin 字段,如果是 taro 在 app.config.js
{
"cloud": true,
"cloudVersion": "alpha"
}
配置生效后,强烈建议在真机进行测试是否异常
cloud: true 能力不支持「一键接入」「自动回退」「中文 URL 参数」等能力,需要手动完成对应能力的实现。可以通过在 app.js 中的 onLaunch 添加如下代码实现劫持 wx.request 实现类似一键接入的效果
// 参考实现,通过劫持 wx.request 完成类似一键接入的效果
App({
onLaunch() {
const gateway = wx.cloud.services.Gateway({
// 接入域名:即在网关接入层生成的域名,请复制“域名配置”中网关的接入域名。
domain: 'a****-********.sh.wxcloudrun.com',
})
// 赋值到 cloud 对象上,方便后续调用
wx.cloud.gateway = gateway
const __origin_req = wx.request;
const gatewayDomainList = [
"https://domain"
] // url 前缀匹配命中 gw_domain_list 中的访问请求,将使用cloudsdk进行访问
function checkGateway(url) {
for (const element of gatewayDomainList) {
if (url.startsWith(element)) {
return true
}
}
return false
}
// 重写 wx.request
wx.request = function (option) {
if (checkGateway(option.url)) {
option.header['X-WX-HTTP-MODE'] = "REROUTE"
option.header['X-WX-CONF-VERSION'] = "0"
return gateway.call({
// 填写完整域名(包括协议头和 host 部分,如 https://api.example.com/path?query=xxx)
// 如果 URL 中包含中文,需要手动 encode
path: option.url,
...option
}).then(option.success).catch(option.fail)
}
return __origin_req(option)
}
}
})
# Taro 等第三方框架
部分第三方框架不支持重写 wx.request,可以使用官方拦截器的方案接入,具体操作如下:
- 创建 gateway.js,内容如下
Taro 示例:
import Taro from '@tarojs/taro'
// 网关域名白名单,以下地址开头的 URL 将会通过网关访问
const GATEWAY_INTERCEPT_URLS = [
'https://example.com'
]
if (Taro.getEnv() === Taro.ENV_TYPE.WEAPP) {
const gateway = wx.cloud.services.Gateway({
// 接入域名:即在网关接入层生成的域名,请复制“域名配置”中网关的接入域名。
domain: '***your-domain***.sh.wxcloudrun.com',
})
const gatewayInterceptor = (chain) => {
const params = chain.requestParams
if (GATEWAY_INTERCEPT_URLS.some(url => params.url.startsWith(url))) {
return gateway.call({
...params,
header: {
...params.header,
'X-WX-HTTP-MODE': 'REROUTE',
'X-WX-CONF-VERSION': '0',
},
path: params.url,
})
} else {
return chain.proceed(params)
}
}
Taro.addInterceptor(gatewayInterceptor)
}
Uniapp 示例:
// #ifdef MP-WEIXIN
// 网关域名白名单,以下地址开头的 URL 将会通过网关访问
const GATEWAY_INTERCEPT_URLS = [
'https://example.com'
]
const gateway = wx.cloud.services.Gateway({
// 接入域名:即在网关接入层生成的域名,请复制“域名配置”中网关的接入域名。
domain: '****.sh.wxcloudrun.com',
})
uni.addInterceptor('request', {
invoke(params) {
if (GATEWAY_INTERCEPT_URLS.some(url => params.url.startsWith(url))) {
return gateway.call({
...params,
header: {
...params.header,
'X-WX-HTTP-MODE': 'REROUTE',
'X-WX-CONF-VERSION': '0',
},
path: params.url,
})
}
},
})
// #endif
- 在 app.js 中,引入上述 JS
import './gateway.js'
- 测试请求是否正常即可
# API 接入
如果需要使用更细粒度的接入方案,可以使用 API 接入的形式:
interface GatewayCallParam {
path: string
header: Record<string, string>
data?: string | ArrayBuffer | any
method?: string
success?: (res: GatewayCallResult) => void
fail?: (err: Error) => void
}
interface GatewayCallResult {
data: any
statusCode: number
header: Record<string, any>
callID: string
}
interface GatewayInstance {
call: (param: GatewayCallParam) => Promise<GatewayCallResult>
}
declare interface WxCloud {
services: {
Gateway: (opts: { domain: string }) => GatewayInstance
}
gateway: GatewayInstance
}
declare interface Wx {
cloud: WxCloud
}
使用示例如下
const gateway = wx.cloud.services.Gateway({
// 接入域名,可以在网关控制台中获取
domain: 'a******.sh.wxcloudrun.com',
})
// 赋值到 cloud 对象上,方便后续调用
wx.cloud.gateway = gateway
const result = wx.cloud.gateway.call({
// 填写完整域名(包括协议头和 host 部分,如 https://api.example.com/path?query=xxx)
// 如果 URL 中包含中文,需要手动 encode
path: 'https://httpbin.org/get?query=xxx',
// 请求方法
method: 'GET',
// 请求 header
header: {
//! 重要:需要携带这个 Header,以启用多域名支持能力
'X-WX-HTTP-MODE': 'REROUTE',
//! 手工接入需要携带的特殊字段,跳过版本号检查
'X-WX-CONF-VERSION': '0',
}
// 其余参数与 wx.request 相同
}).then(result => {
console.log(result)
})
#
# FAQ
Q:手动接入有什么局限性?
- 手动接入请务必自行将网关域名添加到 MP 合法域名中,否则网关将触发链路切换,导致请求变慢或出现异常
- 手动接入时无法使用如下网关能力:链路降级,原生加解密优化,链路预热等,网关性能根据业务场景,会有一定影响。
- 手动接入时,不会自动将 data 中参数转换为 GET URLSearchParam,需要自行转换
- 手动接入时,如果 URL 中包含中文,需要自行进行 encodeURIComponent,否则请求会报错
- 如果网关到期或者超过流量限制,会进入 fail 回调,需要开发者手动处理
Q:手动接入如何灰度流量?
- 手动接入时,可以使用 API 接入的形式,自行决定使用 gateway.call 还是 wx.request 进行请求
Q:手动接入支持到什么版本?
- 微信:2.14.1 基础库版本及以上
- 企业微信:2.20.3 基础库版本及以上
- Web SDK:2.0.3 SDK 版本及以上 具体情况以真机为准,在启用 cloud:true 的小程序中,会提示 using cloud: true 的信息