需求:
在鸿蒙的 web 中通过拦截url,实现h5拉起支付宝或者微信的支付
实现
实现的过程很简单,主要思路就是根据协议拦截url做处理即可。 目前h5拉起支付宝是没有问题的,但是微信支付暂时还不支持。这里就不得不夸奖下阿里,适配很积极,点赞👍
踩坑过程
拦截微信支付携带“Referer”的问题,目前发现onLoadIntercept返回的header数据是空数组,导致无法从header中拿取Referer,当再次执行loadUrl,因无法判断是否已经携带了Referer信息,导致无限循环进入拦截微信支付的逻辑,这里应该是鸿蒙web的问题,暂且解决的办法是在url中添加自定义Parameter。
代码实现
///web请求之前拦截
.onLoadIntercept((event)=>{
if (!event) {return};
const url = event.data.getRequestUrl()
const headers = event.data.getRequestHeader()
const shouldUrlIntercept = this.handleUrlIntercept(url,headers)
return shouldUrlIntercept
})
///处理拦截逻辑
handleUrlIntercept(url:string,headers:Array<Header>): boolean {
///h5拉起支付宝/微信支付
if (url.startsWith("alipays://") || url.startsWith("weixin://")){
const ctx = getContext(this) as common.UIAbilityContext
this.openUrlBySystemBrowse(ctx,url)
return true
}
///拦截h5微信支付添加Referer信息
if (url.startsWith("https://wx.tenpay.com/"){
const payKey = 'xxxxx'
if(!this.getParameter(url, payKey)){
///获取referer
const referer = this.controller.getUrl()
/// url添加自定义 参数
const crossUrl = this.addParameter(url, payKey, '1')
///load一次
this.controller.loadUrl(crossUrl,[{headerKey:"Referer",headerValue:referer}])
return true
}
}
return false
}
///获取url参数
getParameter(url: string, name: string): string {
const r = new RegExp('(\?|#|&)' + name + '=([^&#]*)(&|#|$)'); const m = url.match(r)
return decodeURIComponent(!m ? '' : m[2])
}
///往url中添加参数
addParameter(url: string, key: string, value: string): string {
value = encodeURIComponent(value)
if (url.indexOf(`${key}=`) > -1) {
const reg = new RegExp(`${key}=(\w+)(&|#)?`)
url = url.replace(reg, (match, $1: string, $2: string) => {
return `${key}=${value}${$2 || ''}`
})
} else {
if (url.indexOf('?') > -1) {
url = url.replace('?', `?${key}=${value}&`)
} else {
url = `${url}?${key}=${value}`
}
}
return url
}
///使用手机系统浏览器打开url
openUrlBySystemBrowse(context: common.UIAbilityContext,url:string): Promise<void> {
let want: Want = {
action: 'ohos.want.action.viewData',
entities: ['entity.system.browsable'],
uri: url,
};
return context.startAbility(want)
}