华为鸿蒙浏览器的支付宝支付问题解决

Wednesday , 2022-4-20 18:05

事情是这样的,现在的vue3+ts项目需要用到支付宝支付,支付的方式都很简单,就是获取form表单然后提交即可,但是在鸿蒙的自带浏览器中出现了诡异的情况,主要表现在

  • 在支付表单提交后,点击返回,页面不会有任何刷新(其他的手机浏览器是会重新加载),这样也就监听不到生命周期中的任何函数,对于程序来说,就好像这次跳转根本不存在,这还不是最离谱的!
  • 当我从支付页面返回到首页,这个时候变换支付参数再去发起表单提交,华为的自带浏览器居然没用重新加载,还是用的之前的表单提交,导致买的品类还是之前的订单。这就离了大谱了!!!

机智如我,先是尝试了生命周期的调试,无效,根本没有任何反应,遂放弃!

于是我先,如果判断华为浏览器,然后将表单的target=_blank在新页面打开呢?

嘿,结果您猜怎么着?这个属性华为浏览器直接没反应,诶,就是雷打不动…..

怎么办呢?

看来曲线救国是不行了,得来硬的,好在window.open() 这个方法还能用,思路大概是通过浏览器标识判断是华为浏览器,此时新开一个页面,将请求到的form数据存在sessionStorage(url参数方式带表单太长,着实是有点不优雅),然后在/huaweiPay的这个页面中获取sessionStorage中的表单数据提交。

看码:

1
2
3
4
5
6
7
8
9
10
//util.ts 中封装浏览器标识判断
export function navigatorMark(curr:string='') {//获取浏览器标记
const userAgent = navigator.userAgent.toUpperCase();
console.log(userAgent)
if(curr){
curr = curr.toUpperCase();
return userAgent.indexOf(curr)>-1;
}
return userAgent;
}//navigatorMark
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// payment.ts 封装的支付宝支付
export function AlipayPay(form: string) {
if(navigatorMark('HUAWEI')){//华为鸿蒙的垃圾浏览器,要单独做兼容
sessionStorage.setItem('HaweiPayForm',form);
setTimeout(() => {
sessionStorage.removeItem('HaweiPayForm');
}, 50);
window.open(`${getHostUrl()}/huaweiPay`);
return false;
}
//下面是正常支付
let div = document.createElement('div');
div.id = 'payDom';
div.style.display = 'none';
div.innerHTML = form;
document.body.appendChild(div);
setTimeout(() => {
let formDom = document.getElementById('payDom')?.getElementsByTagName('form')[0];
formDom?.submit();
}, 10);
} //AlipayPay
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<!-- /huaweiPay 的路由页面 -->

<template>
<div id="huaweiPay">
<!-- 华为鸿蒙系统的垃圾浏览器,做了缓存,提交支付表单不会刷新,返回也监听不到生命周期,所以单开一个页面做支付,国产系统还有很长的路要走啊,可愁死我了!!!! -->
<p class="info">订单支付中....</p>
<div id="payDom"></div>
</div>
</template>

<script lang="ts">
import { defineComponent, ref} from "vue";

export default defineComponent({
setup() {
const formDom = ref<string | null>(sessionStorage.getItem('HaweiPayForm'));
if(!formDom.value){
return false;
}else{
sessionStorage.removeItem('HaweiPayForm');//安全起见,插入表单之后就删除
setTimeout(() => {//有dom插入,延迟300ms
let payDom = (document.getElementById('payDom') as HTMLBaseElement);
payDom.innerHTML = formDom.value as string;
payDom.getElementsByTagName('form')[0]?.submit();
}, 300);
}
return {
formDom
};
}, //setup
});
</script>

补充知识,sessionStorage像上述这样的跳转,A->B,A的数据会拷贝到B,但是B的删除不会对A,A的操作同理也不会影响到B,他们相互独立管理。

如上所述,相同的问题在调整过程中,Android开发的同事也有反应,在对鸿蒙系统做兼容的时候很痛苦,或许我们应该理性看待,国产系统真的还有很长的路要走…..