uniapp 微信小程序webview 和 h5数据通信

ops/2024/12/12 13:23:01/

项目是uniapp编写,因为是先开发了h5和app,小程序是突然要用的,做兼容开发已经来不及,由于微信小程序webview载入h5 因为通信必须要特殊限制(网页向小程序 postMessage 时,会在以下特定时机触发并收到消息:小程序后退、组件销毁、分享、复制链接(2.31.1)。e.detail = { data },data是多次 postMessage 的参数组成的数组。),不能满足使用,所以搞了一套特别low的通信机制,缺点是通信时候会有一个loading的过渡页面

业务逻辑大致为:
1、微信小程序webview访问h5带参数的url,获取初始的参数,可以携带页面参数或者登录token等,通过reciver接受h5返回的参数。
2、h5通过一个中间html页面存储小程序的通信逻辑,然后在h5页面通过定时器一直获取缓存本地的数据,根据数据信息执行不同的业务逻辑

1、微信小程序项目
(1)微信小程序项目
index.vue

<template><web-view v-if="src" :src="src" bindload="bindload" binderror="binderror"></web-view>
</template><script lang="ts">
import { cfg } from '@/cfg'
import Base64 from '@/utils/Base64'export default {data() {return {src: '',}},onLoad(e: any) {let loginA = parseInt(e.loginA)console.log(e.loginA)if (loginA) {let self = thiswx.login({success(res: any) {// 自动登录成功self.msg(Base64.encode64('loginA,' + JSON.stringify([loginA, cfg.mpApp, res.code])))},fail(res: any) {// 自动登录失败self.msg(Base64.encode64('loginAFail,' + JSON.stringify([loginA, res.errMsg])))},})return}this.msg(e.msg)},methods: {msg(msg: any) {if (msg) {this.src = cfg.mpUrl + 'static/mpMsg.html?uid=' + cfg.mpid + '&msg=' + msg// this.src = 'http://www.baidu.com/#/'console.log(this.src)// 超时自动关闭// @ts-ignorethis['$timer'] = setTimeout(() => {this.navBack()}, 3000)return}this.navBack()},bindload() {console.log('bindload')this.navBack()},binderror() {console.log('binderror')this.navBack()},navBack() {let pages = getCurrentPages()if (pages[pages.length - 1].$vm == this) {uni.navigateBack()}// @ts-ignorelet timer = this['$timer']if (timer) {// @ts-ignoredelete this['$timer']clearTimeout(timer)}},},
}
</script><style></style>

(2)reciver.vue

<template><view id="preloader"></view>
</template><script lang="ts">
import { App } from '@/store/app'
import Base64 from '@/utils/Base64'export default {data() {return {src: '',}},onLoad(e: any) {try {let msg = e.msgif (msg) {msg = Base64.decode64(msg)let i = msg.indexOf(',')let key = msglet val = ''if (i > 0) {key = msg.substring(0, i)val = msg.substring(i + 1)}// 如果是pc小程序bridge支付,则直接跳转到支付页面// const info = uni.getSystemInfoSync()// if ((info?.deviceType == 'pc' || info?.deviceType == 'PC') && key == 'pay') {//   uni.redirectTo({//     url: `/pages/index/pay?pay=${Base64.encode64(val)}`,//   })// } else {//   uni.navigateBack({//     complete() {//       // setTimeout(() => {//       App.mpRecieverMsg(key, val)//       // }, 100)//     },//   })// }uni.navigateBack({complete() {// setTimeout(() => {App.mpRecieverMsg(key, val)// }, 100)},})return}} catch (e) {console.error(e)}uni.navigateBack()},methods: {},
}
</script><style scoped>
#preloader {position: absolute;width: 30px;height: 30px;background: rgba(253, 87, 17, 1);border-radius: 50px;left: 0;right: 0;top: 0;bottom: 0;margin: auto;-webkit-animation: preloader_1 1.5s infinite linear;-moz-animation: preloader_1 1.5s infinite linear;-ms-animation: preloader_1 1.5s infinite linear;animation: preloader_1 1.5s infinite linear;
}
#preloader:after {position: absolute;width: 50px;height: 50px;border-top: 10px solid rgba(255, 139, 9, 1);border-bottom: 10px solid rgba(255, 139, 9, 1);border-left: 10px solid transparent;border-right: 10px solid transparent;border-radius: 50px;content: '';top: -20px;left: -20px;-webkit-animation: preloader_1_after 1.5s infinite linear;-moz-animation: preloader_1_after 1.5s infinite linear;-ms-animation: preloader_1_after 1.5s infinite linear;animation: preloader_1_after 1.5s infinite linear;
}@-webkit-keyframes preloader_1 {0% {-webkit-transform: rotate(0deg);}50% {-webkit-transform: rotate(180deg);background: #ff4f11;}100% {-webkit-transform: rotate(360deg);}
}
@-webkit-keyframes preloader_1_after {0% {border-top: 10px solid rgba(253, 87, 17, 1);border-bottom: 10px solid rgba(255, 139, 9, 1);}50% {border-top: 10px solid rgba(253, 87, 17, 1);border-bottom: 10px solid rgba(253, 87, 17, 1);}100% {border-top: 10px solid rgba(255, 139, 9, 1);border-bottom: 10px solid rgba(255, 139, 9, 1);}
}@-moz-keyframes preloader_1 {0% {-moz-transform: rotate(0deg);}50% {-moz-transform: rotate(180deg);background: #ff4f11;}100% {-moz-transform: rotate(360deg);}
}
@-moz-keyframes preloader_1_after {0% {border-top: 10px solid rgba(255, 139, 9, 1);border-bottom: 10px solid rgba(255, 139, 9, 1);}50% {border-top: 10px solid rgba(253, 87, 17, 1);border-bottom: 10px solid rgba(253, 87, 17, 1);}100% {border-top: 10px solid rgba(255, 139, 9, 1);border-bottom: 10px solid rgba(255, 139, 9, 1);}
}@-ms-keyframes preloader_1 {0% {-ms-transform: rotate(0deg);}50% {-ms-transform: rotate(180deg);background: #ff4f11;}100% {-ms-transform: rotate(360deg);}
}
@-ms-keyframes preloader_1_after {0% {border-top: 10px solid rgba(255, 139, 9, 1);border-bottom: 10px solid rgba(255, 139, 9, 1);}50% {border-top: 10px solid rgba(253, 87, 17, 1);border-bottom: 10px solid rgba(253, 87, 17, 1);}100% {border-top: 10px solid rgba(255, 139, 9, 1);border-bottom: 10px solid rgba(255, 139, 9, 1);}
}@keyframes preloader_1 {0% {transform: rotate(0deg);}50% {transform: rotate(180deg);background: #ff4f11;}100% {transform: rotate(360deg);}
}
@keyframes preloader_1_after {0% {border-top: 10px solid rgba(255, 139, 9, 1);border-bottom: 10px solid rgba(255, 139, 9, 1);}50% {border-top: 10px solid rgba(253, 87, 17, 1);border-bottom: 10px solid rgba(253, 87, 17, 1);}100% {border-top: 10px solid rgba(255, 139, 9, 1);border-bottom: 10px solid rgba(255, 139, 9, 1);}
}
</style>

(3)app.ts

import cfg from '@/cfg'
import Base64 from '@/utils/Base64'export const App = {shareData: {},mpPostMsg(key: string, val?: string, redirect: boolean = true) {const msg = val ? key + ',' + val : keyif (redirect) {uni.redirectTo({ url: '/pages/msg/post?msg=' + Base64.encode64(msg) })} else {uni.navigateTo({ url: '/pages/msg/post?msg=' + Base64.encode64(msg) })}},mpRecievers: {userStorageCert(cert: string) {console.log('userCert', cert)if (cert) {uni.setStorageSync(cfg.mpApp + 'userStorageCert', cert)}},shareAppMessage(v: string) {let sharetry {share = JSON.parse(v)if (share.path) {// 使用正则表达式匹配 _i= 后面的字符串const match1 = share.path.match(/_i=([^&]+)/)// 如果匹配成功,获取匹配到的字符串if (match1) {const extractedString = match1[1]share.path = '/pages/index/index?i=' + extractedStringconsole.log(' share.path', share.path)}}} catch (error) {}try {if (share.imageUrl) {share.imageUrl = share.imageUrl.replace(/(w_\d+)|(h_\d+)/g, (match: string) => {if (match.startsWith('w_')) {return 'w_300'} else if (match.startsWith('h_')) {return 'h_300'}})}} catch (error) {}if (share) {App.shareData = share}},pay(v: string) {const pay = JSON.parse(v)pay.success = function () {// 需要通知App.mpPostMsg('pay,1', undefined, false)}// pay.complete = function () {//   // 需要通知//   App.mpPostMsg('pay,1', undefined, false)// }pay.fail = function (e: any) {console.log('pay fail ' + JSON.stringify(e))uni.showToast({title: '支付失败',icon: 'none',duration: 2000,})}// 支付参数console.log(JSON.stringify(pay))const info = uni.getSystemInfoSync()// 如果是pc小程序bridge支付,则延迟掉起,防止不显示支付弹窗if (info?.deviceType == 'pc' || info?.deviceType == 'PC') {uni.showLoading()setTimeout(() => {uni.hideLoading()wx.requestPayment(pay)}, 1000)} else {wx.requestPayment(pay)}},bindWx() {wx.login({success: function (res: any) {let data = ''if (res) {let appid = ''if (cfg.mpApp) {appid = cfg.mpApp}data = JSON.stringify([appid, res.code])}App.mpPostMsg('bindWx', data, false)},fail: function (err: any) {console.log('bindWx fail', err)App.mpPostMsg('bindWx', '', false)},})},openLocation(adress: string) {const data = JSON.parse(adress)wx.openLocation({latitude: Number(data.latitude),longitude: Number(data.longitude),name: data.name,scale: 18,complete: e => {console.log('openLocation complete', e)},})console.log('openLocation data', data)},downloadAndSave(res: string) {const data = JSON.parse(res)const $delay = data['$delay']if ($delay > 0) {setTimeout(() => {wx.downloadFile({url: data.url,success: function (res) {wx.openDocument({filePath: res.tempFilePath,fileType: 'pdf',showMenu: true,})},})}, $delay)} else {wx.downloadFile({url: data.url,success: function (res) {wx.openDocument({filePath: res.tempFilePath,fileType: 'pdf',showMenu: true,})},})}},callFun(res: string) {const data = JSON.parse(res)// @ts-ignoreconst fun = wx[data['$fun']]if (fun) {delete data['$fun']const $delay = data['$delay']if ($delay > 0) {delete data['$delay']setTimeout(() => {fun.call(wx, data)}, $delay)} else {fun.call(wx, data)}}},},mpRecieverMsg(key: string, val?: string) {// @ts-ignoreconst fun = App.mpRecievers[key]if (fun) {fun(val)return}},
}

(3)Base64.ts

// private property
let _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";// private method for UTF-8 encoding
let _utf8_encode = function (str: string) {str = str.replace(/\r\n/g, "\n");let utftext = "";for (let n = 0; n < str.length; n++) {let c = str.charCodeAt(n);if (c < 128) {utftext += String.fromCharCode(c);} else if ((c > 127) && (c < 2048)) {utftext += String.fromCharCode((c >> 6) | 192);utftext += String.fromCharCode((c & 63) | 128);} else {utftext += String.fromCharCode((c >> 12) | 224);utftext += String.fromCharCode(((c >> 6) & 63) | 128);utftext += String.fromCharCode((c & 63) | 128);}}return utftext;
}// private method for UTF-8 decoding
let _utf8_decode = function (utftext: string) {let string = "";let i = 0;let c, c1, c2, c3c = c1 = c2 = 0;while (i < utftext.length) {c = utftext.charCodeAt(i);if (c < 128) {string += String.fromCharCode(c);i++;} else if ((c > 191) && (c < 224)) {c2 = utftext.charCodeAt(i + 1);string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));i += 2;} else {c2 = utftext.charCodeAt(i + 1);c3 = utftext.charCodeAt(i + 2);string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));i += 3;}}return string;
}const Base64 = {// public method for encodingencode(input: string) {let output = "";let chr1, chr2, chr3, enc1, enc2, enc3, enc4;let i = 0;input = _utf8_encode(input);while (i < input.length) {chr1 = input.charCodeAt(i++);chr2 = input.charCodeAt(i++);chr3 = input.charCodeAt(i++);enc1 = chr1 >> 2;enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);enc4 = chr3 & 63;if (isNaN(chr2)) {enc3 = enc4 = 64;} else if (isNaN(chr3)) {enc4 = 64;}output = output +_keyStr.charAt(enc1) + _keyStr.charAt(enc2) +_keyStr.charAt(enc3) + _keyStr.charAt(enc4);}return output;},// public method for decodingdecode(input: string) {let output = "";let chr1, chr2, chr3;let enc1, enc2, enc3, enc4;let i = 0;input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");while (i < input.length) {enc1 = _keyStr.indexOf(input.charAt(i++));enc2 = _keyStr.indexOf(input.charAt(i++));enc3 = _keyStr.indexOf(input.charAt(i++));enc4 = _keyStr.indexOf(input.charAt(i++));chr1 = (enc1 << 2) | (enc2 >> 4);chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);chr3 = ((enc3 & 3) << 6) | enc4;output = output + String.fromCharCode(chr1);if (enc3 != 64) {output = output + String.fromCharCode(chr2);}if (enc4 != 64) {output = output + String.fromCharCode(chr3);}}output = _utf8_decode(output);return output;},// 编码encode64(str: string, uri: boolean = true) {str = Base64.encode(str);if (uri) {str = str.replace(/[+|=|/]/g, function (word) {switch (word) {case "+":return "-";case "=":return "_";case "/":return ".";}return word;});}return str;},// 解码decode64(str: string, uri: boolean = true) {if (uri) {str = str.replace(/[-|_|.]/g, function (word) {switch (word) {case "-":return "+";case "_":return "=";case ".":return "/";}return word;});}str = Base64.decode(str);return str;},
}export default Base64

index.vue

<template><web-view :src="src" @message="receiveMessage"> </web-view>
</template><script lang="ts">
import { cfg } from '@/cfg'
import { App } from '@/store/app'
import Base64 from '@/utils/Base64'
export default {data() {return {src: '',srcP: '',shareData: {imageUrl:'https://yjy.yiyiny.com//static/images/20240122/' +cfg.mpApp +'.png?x-oss-process=image/auto-orient,1/resize,m_fixed,w_100,h_100',},shareI: '',}},onLoad(e: any) {// e.scene  生成小程序码必须是这个keythis.setSrc(cfg.entryUrl, e.i || e.scene)wx.showShareMenu({withShareTicket: true,menus: ['shareAppMessage'],success(res) {console.log('mixin share success', res ? JSON.stringify(res) : res)},fail(err) {console.log('mixin share fail', err ? JSON.stringify(err) : err)},})},onShow() {cfg.mpSrcP = this.srcPApp.shareData = {}},onShareAppMessage(res: any) {console.log(res)if (res.from === 'button') {return this.shareData}if (res.from === 'menu') {return this.shareData || {}}},onShareTimeline() {let data = {title: '一乙艺术山庄',query: 'id=1',// imageUrl: '',}return data// return axCc.vueSelf.shareData || {};},onHide() {},methods: {setSrc(src: string, shareI?: string) {let cert = uni.getStorageSync(cfg.mpApp + 'userStorageCert')console.log('setSrc src', src)console.log('setSrc shareI', shareI)let i = src.indexOf('#')let j = src.indexOf('?')let srcP = i > 0 && i < j ? src.substring(0, i) : j > 0 ? src.substring(0, j) : srcif (srcP && srcP[srcP.length - 1] != '/') {srcP = srcP + '/'}if (i > 0) {cfg.mpUrl = src.substring(0, i)} else {cfg.mpUrl = cfg.entryUrl}console.log('[  cfg.mpUrl ] >', cfg.mpUrl)this.srcP = srcPcfg.mpSrcP = this.srcPsrc = j > 0 ? src + '&_mpid_=' + cfg.mpid : src + '?_mpid_=' + cfg.mpidif (shareI) {src = src + '&_i=' + shareI// 分享地址拼接const startIndex = src.indexOf('#')const endIndex = src.indexOf('?')if (startIndex !== -1 && endIndex !== -1) {src = src.substring(0, startIndex) + src.substring(endIndex)console.log(src)}this.shareI = shareI}src = src + '&ver=' + cfg.versionif (cert) {src = src + '&_cert_=' + encodeURIComponent(cert)}this.src = srcconsole.log('setSrc this.src', this.src)},// 监听h5 消息// { merber 用户信息 imageUrl 默认分享图 path 分享地址 title:分享标题   desc }receiveMessage(e: any) {console.log('receiveMessage333', e)let arr = e?.detail?.datalet data = arr && arr.length > 0 ? arr[arr.length - 1] : nulllet urlif (data && data?.merber?.id) {url = data?.path? data.path: cfg.mpName == 'mp_wdysj'? 'pages/artisthome/artisthome': '/pagesShop/shop/wHome'let parms = this.gen(url, false, { mmId: data?.merber.id }, 13050, data?.merber?.id)console.log('data222', data)this.shareData = {path: '/pages/index/index?i=' + parms + '&fk=1',imageUrl: data?.imageUrl? data.imageUrl: 'https://yjy.yiyiny.com//static/images/20240122/' +cfg.mpApp +'.png?x-oss-process=image/auto-orient,1/resize,m_fixed,w_100,h_100',title: data?.title ? data.title : cfg.mpName,desc: data?.desc ? data.desc : '',query: parms,}} else {wx.hideShareMenu()}},// 地址加密gen(uri: string, bind: boolean, reg: any, eid?: number, memberId?: number): string {// 标准编码let ps = [memberId, '', false, uri || '', reg || '', eid]for (let i = ps.length - 1; i >= 0; i--) {if (ps[i]) {let del = ps.length - i - 1if (del > 0) {ps.splice(i + 1, del)}break}}let _ps: any = ps_ps[0] = _ps[0] || ''if (bind) {_ps[2] = uri_ps[3] = ''} else {_ps[2] = ''}return Base64.encode64(JSON.stringify(ps))},},
}
</script><style></style>

cfg.ts

export const cfg = {mpApp: 'mp_wdysj', //一乙艺术商城mpName: '一乙艺术商城',mpUrl: 'https://p.yiyiny.com/xxx/',mpid: '',mpSrcP: '',version: '1.0.8',entryUrl: 'https://p.yiyiny.com/xxx/#/pagesShop/shop/wHome',
}const info = uni.getSystemInfoSync()
if (!cfg.mpid) {const host = info.host// @ts-ignoreif (host && host.appid) {// @ts-ignorecfg.mpid = host.appid}if (!cfg.mpid) {cfg.mpid = cfg.mpApp}
}
export default cfg

2、h5端
(1)项目初始化时候h5载入微信sdk
Ainit.ts

 // #ifdef H5let _mpid_;try {let search = <any>((launcher.h5Search || ab_.route(false, false, false).search));_mpid_ = search['_mpid_'];let _cert_ = search['_cert_'];// 获取小程序传递的证书if (_cert_) {_cert_ = decodeURIComponent(_cert_)User.status.storage.cert = _cert_}let app = axConfig.webType || 'web'if (Weixin.isWeiXin()) {axCc.Loader().wait("weixinLogin");ab_.reqJs(axCc.https? "https://res.wx.qq.com/open/js/jweixin-1.6.0.js": "http://res.wx.qq.com/open/js/jweixin-1.6.0.js",null,function () {function wxH5() {if (search["code"]) {let parms: Array<string> = [axConfig.webType, search["code"]];User.loginProvBack("wx",function (logined) {console.log("微信登陆成功", logined);try {if (logined) {axCc.saveStorage("wxLogined", {token: App.client.plt.headers["atoken"],authPar: User.status.authPar,authParas: User.status.authParas,});} else {axCc.saveStorage("wxLogined", {});}} finally {axCc.Loader().done("weixinLogin");// 微信jsConfigWeixin.wxConfig();}},parms,true,true,true);} else {try {// 关闭自动登录// User.autoLogin = false;let wxLogined = axCc.getStorage("wxLogined");if (wxLogined && wxLogined.token && wxLogined.authParas && wxLogined.authParas[0] === app) {User.loginToken(wxLogined.token, (logined) => {if (logined) {User.status.authPar = wxLogined.authPar;User.status.authParas = wxLogined.authParas;axCc.Loader().done("weixinLogin");} else {//微信浏览器 吊起微信支付必须要获取openidconsole.log("掉起微信支付必须要获取openid");Weixin.snsapi_base();}});} else {//微信浏览器 吊起微信支付必须要获取openidconsole.log("掉起微信支付必须要获取openid");Weixin.snsapi_base();}} finally {// 微信jsConfigWeixin.wxConfig();}}}// @ts-ignoreif (window.wx) {User.autoLogin = false;try {// @ts-ignoreif (typeof WeixinJSBridge == "object" && typeof WeixinJSBridge.invoke == "function") {handleFontSize();} else {if (document.addEventListener) {document.addEventListener("WeixinJSBridgeReady", handleFontSize, false);// @ts-ignore} else if (document.attachEvent) {// @ts-ignoredocument.attachEvent("WeixinJSBridgeReady", handleFontSize);// @ts-ignoredocument.attachEvent("onWeixinJSBridgeReady", handleFontSize);}}function handleFontSize() {// 设置网页字体为默认大小// @ts-ignoreWeixinJSBridge.invoke('setFontSizeCallback', { 'fontSize': 0 });// 重写设置网页字体大小的事件// @ts-ignoreWeixinJSBridge.on('menu:setfont', function () {// @ts-ignoreWeixinJSBridge.invoke('setFontSizeCallback', { 'fontSize': 0 });});}// @ts-ignoreif (wx.miniProgram) {// @ts-ignorewx.miniProgram.getEnv((res) => {if (res.miniprogram) {User.status.info.cert = trueUser.autoLogin = true;// && search['_mpid_'] == "mp_wdysj_shop"if (_mpid_) {if ((_mpid_ == "mp_wdysj_shop" || _mpid_ == "mp_wdysj_yiyi_shop")) {axConfig.pltName = "商城"axConfig.home = "/pagesShop/shop/wHome"App.shopScoreName = '商城'App.client.storeHttp.head('platform', 'mp')axConfig.appProv = _mpid_axConfig.appEid = 13061}axConfig.pltApp = _mpid_User.status.info.app = _mpid_}// 小程序Weixin.initWxMpH5(_mpid_, search['ver'])axCc.Loader().done("weixinLogin");} else {wxH5()}})return}} catch (e) {console.error(e)}wxH5()} else {axCc.Loader().done("weixinLogin");}},undefined);} else {}} catch (e) {console.error(e);}// #endif

2、Weixin.ts

import ab_ from 'axj-ab_'; //npm install axj-ab_
import Base64 from '../util/Base64';interface ShareInfo {title: string,desc?: string,link: string,imageUrl?: string,logo?: string,//兼容老项目imgUrl?: string,//兼容老项目scene?: string
}let weixin = false;
let readyReg = false;
let wxConfigState = -1;
let wxMpH5 = false;
let wxMpApp = '';
// let wxMpToken = '';const Weixin = {initStepsArray: [1000, 2000, 4000, 8000, 16000, 32000, 64000],initI: 0,erred: false,readyed: false,shareInfo: <undefined | ShareInfo>undefined,// 如果wx授权失败,则定时再次获取授权wxConfigRe(e?: any) {console.log('wxConfig error ' + e)// alert('wxConfig error ' + JSON.stringify(e))Weixin.erred = true// @ts-ignoresetTimeout(Weixin.wxConfig, Weixin.initI < Weixin.initStepsArray.length ? Weixin.initStepsArray[Weixin.initI++] : Weixin.initStepsArray[Weixin.initStepsArray.length - 1])},// 通过config接口注入权限验证配置wxConfig() {let authUrl = location.hrefwxConfigState++switch (wxConfigState) {case 1:authUrl = Ainit.h5Hrefbreak// case 2://   authUrl = location.protocol + '//' + location.host + location.pathname + location.search + location.hash//   breakdefault:wxConfigState = 0break}//调接口授权的方法可以自己写App.client.plt.reqA(-1, 'C/wxConfig', [axConfig.webType, authUrl], function (err, rep) {console.log('pltClient C/wxConfig err,data:', err, rep)if (rep && rep.appId) {// rep.debug = truerep.jsApiList = ['updateAppMessageShareData','updateTimelineShareData','onMenuShareAppMessage','onMenuShareTimeline',"getLocation","scanQRCode",// 'wx-open-launch-weapp',// 'chooseWXPay']// rep.debug = trueconsole.log('wxready  wx.config')Weixin.erred = false// @ts-ignorewx.config(rep)// @ts-ignorewx.error(Weixin.wxConfigRe)let readyFun = function () {if (Weixin.erred) {return}Weixin.readyed = true}if (readyReg) {setTimeout(readyFun, 1000);} else {readyReg = true// @ts-ignorewx.ready(readyFun)}return;}Weixin.wxConfigRe()})},wxShare(v: ShareInfo) {console.log('h5  wxShare alert', v);if (weixin) {// @ts-ignorev = typeof (v) === 'object' ? v : JSON.parse(v)if (!Weixin.readyed) {Weixin.shareInfo = vreturn}delete Weixin.shareInfovar share = {title: v.title || 'xx', // 分享标题desc: v.desc || '', // 分享描述link: v.link, // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致imgUrl: v.imageUrl || v.logo || v.imgUrl, // 分享图标success: (e) => {console.log('wxShare success  ', e)// 显示微信分享// @ts-ignore// if (window.WeixinJSBridge) {//   // @ts-ignore//   window.WeixinJSBridge.call('showOptionMenu')// }if (window.wx && window.wx.showMenuItems) {// @ts-ignorewindow.wx.showMenuItems({menuList: ['menuItem:share:appMessage','menuItem:share:timeline','menuItem:favorite','menuItem:share:qq','menuItem:share:QZone',]})}},fail: function (e) {console.log('wxShare fail', e)}}console.log('updateWx', share)// @ts-ignorewx.updateAppMessageShareData(share)// @ts-ignorewx.updateTimelineShareData(share)// WeixinJSBridge.call("showOptionMenu");}},// 静默授权snsapi_base() {var backUri = Ainit.h5Href || location.hrefconsole.log(backUri)var redirectUri = axConfig.pltH5 + 'static/wx.html?u=' + Base64.encode64(backUri, true)redirectUri ='https://open.weixin.qq.com/connect/oauth2/authorize?appid=' + (axConfig.webType == 'wdysjh5' ? 'wxab385cf8a7ec96d8' : 'wx59a0fb7a9bd076e5') + '&redirect_uri=' +encodeURIComponent(redirectUri) +'&response_type=code&scope=snsapi_userinfo&state=1'console.log(redirectUri)location.replace(redirectUri)// setTimeout(() => {//   location.replace(redirectUri)// }, 3000);},isWeiXin() {return weixin;},isWxMpH5() {return wxMpH5},getWxMpApp() {return wxMpApp},initWxMpH5(mpid: string, ver?: string) {console.log('initWxMpH5 ' + mpid)weixin = falsewxMpH5 = trueif (mpid) {wxMpApp = mpid} else {console.log('initWxMpH5 no mpid' + location.href)console.log(launcher.h5Href)console.log(launcher.h5Search)}Artist.getReviewVersion(`mp-${ver}`)// 消息通道setInterval(function () {let msg = localStorage.getItem('_mpmsg_')if (msg) {try {msg = JSON.parse(msg)if (!mpid || msg[0] === mpid) {// 是发给我的消息msg = msg[1]msg = Base64.decode64(msg)let i = msg.indexOf(',')if (i > 0) {Weixin.onWxMpMsg(msg.substring(0, i), msg.substring(i + 1))} else {Weixin.onWxMpMsg(msg, '')}localStorage.removeItem('_mpmsg_')}} catch (e) {console.error(e)localStorage.removeItem('_mpmsg_')}}}, 100)},onWxMpMsg(key: string, val?: string) {console.log('onWxMpMsg,' + key + ',' + val)if (key == 'pay') {console.log('updatePay,更新支付状态' + key)uni.$emit('updatePay', { msg: '更新支付状态' })}// @ts-ignorewx.miniProgram.navigateBack()let fun = Weixin.onWxMpCenter[key]if (fun) {fun(val)}},forWxMpToken(back: (err?: any) => void) {if (User.status.authPar) {back && back()return}// @ts-ignorelet nextT = ab_.nextT()// @ts-ignoreWeixin['forWxMpTokenBacks'] = [nextT, back]// @ts-ignorewx.miniProgram.navigateTo({ url: '/pages/msg/post?loginA=' + nextT })},onWxMpCenter: {loginA(val: string) {let paras = JSON.parse(val)let nextT = 0let back: anylet loginA = falseif (typeof (paras[0]) === 'number') {loginA = truenextT = paras[0]paras = ab_.args(paras, 1, paras.length)let backs = Weixin['forWxMpTokenBacks']if (backs) {delete Weixin['forWxMpTokenBacks']if (backs[0] === nextT) {back = backs[1]}}}let noRep = nextT && User.state.loginedUser.loginProvBack('wx', (succ, rep) => {console.log('loginA ', succ, rep)if (succ) {Page.loginSuccBack()if (loginA) {// @ts-ignorewx.miniProgram.navigateBack()}} else if (!User.state.authing && !nextT) {console.log('toLogin--------')Weixin.postWxMpMsg('toLogin')}// 回调back && back(User.status.authToken ? undefined : rep)}, paras, false, 2, false, noRep)},loginAFail(val: string) {let paras = JSON.parse(val)let nextT = paras[0]let backs = Weixin['forWxMpTokenBacks']if (backs) {delete Weixin['forWxMpTokenBacks']if (backs[0] === nextT) {backs[1] && backs[1](paras[1])}}},loginInfo(val: string) {//let loginInfo = JSON.parse(val)let paras = JSON.parse(val)if (User.status.authToken) {paras[1] = User.status.authToken}User.loginProvBack('wx', (succ) => {if (succ) {Page.loginSuccBack()} else if (!User.state.authing) {User.status.authToken = ''}}, paras, true, 2)},bindWx(val: string) {uni.$emit('updateBindWx', { msg: val })}},postWxMpMsg(key: string, val?: string) {console.log('postWxMpMsg,' + key + ',' + val)if (key === 'toLogin') {// ios 微信新用户第一次登录 会导致不执行此逻辑setTimeout(() => {// @ts-ignorewx.miniProgram.navigateTo({ url: '/pages/index/login?t=' + User.status.authToken })}, 400);return}// if (key === 'toLoginA') {//   // @ts-ignore//   wx.miniProgram.navigateTo({ url: '/pages/index/login' })//   return// }if (key === 'share') {// @ts-ignorewx.miniProgram.navigateTo({ url: '/pages/msg/share?s=' + val })return}let msg = val ? (key + ',' + val) : keysetTimeout(() => {// @ts-ignorewx.miniProgram.navigateTo({ url: '/pages/msg/reciver?msg=' + Base64.encode64(msg) })}, 400);console.log('postWxMpMsg.navigateTo');},
}// #ifdef H5
try {// 微信环境判断let userAgent: any = window.navigator.userAgent.toLowerCase();weixin =userAgent.match(/MicroMessenger/i) == "micromessenger" &&!(window.parent && window.parent !== window);//兼容 微信支付路径if (weixin) {let h5Uri = location.href;if (h5Uri.indexOf('/#/') < 0) {// axCc.Loader().wait("weixinHref");try {h5Uri = location.origin + location.pathname + "#/" + location.searchlocation.href = h5UrisetTimeout(() => {location.reload()}, 1000);axCc.Loader().wait("weixinHref");} catch (error) {}}}} catch (e) {console.error(e);
}
// #endifexport default Weixin;

3、公共h5跳转页

<html><head><meta charset="utf-8" /><metaname="viewport"content="width=device-width,initial-scale=1.0,maximum-scale=1,viewport-fit=cover"/><title>···</title><style>#loadingBg {width: 100vw;height: 100vh;position: fixed;z-index: 10000;top: 0;}body {margin: 0px;font-size: 12px;}#preloader {position: absolute;width: 30px;height: 30px;background: rgba(253, 87, 17, 1);border-radius: 50px;left: 0;right: 0;top: 0;bottom: 0;margin: auto;-webkit-animation: preloader_1 1.5s infinite linear;-moz-animation: preloader_1 1.5s infinite linear;-ms-animation: preloader_1 1.5s infinite linear;animation: preloader_1 1.5s infinite linear;}#preloader:after {position: absolute;width: 50px;height: 50px;border-top: 10px solid rgba(255, 139, 9, 1);border-bottom: 10px solid rgba(255, 139, 9, 1);border-left: 10px solid transparent;border-right: 10px solid transparent;border-radius: 50px;content: "";top: -20px;left: -20px;-webkit-animation: preloader_1_after 1.5s infinite linear;-moz-animation: preloader_1_after 1.5s infinite linear;-ms-animation: preloader_1_after 1.5s infinite linear;animation: preloader_1_after 1.5s infinite linear;}@-webkit-keyframes preloader_1 {0% {-webkit-transform: rotate(0deg);}50% {-webkit-transform: rotate(180deg);background: #ff4f11;}100% {-webkit-transform: rotate(360deg);}}@-webkit-keyframes preloader_1_after {0% {border-top: 10px solid rgba(253, 87, 17, 1);border-bottom: 10px solid rgba(255, 139, 9, 1);}50% {border-top: 10px solid rgba(253, 87, 17, 1);border-bottom: 10px solid rgba(253, 87, 17, 1);}100% {border-top: 10px solid rgba(255, 139, 9, 1);border-bottom: 10px solid rgba(255, 139, 9, 1);}}@-moz-keyframes preloader_1 {0% {-moz-transform: rotate(0deg);}50% {-moz-transform: rotate(180deg);background: #ff4f11;}100% {-moz-transform: rotate(360deg);}}@-moz-keyframes preloader_1_after {0% {border-top: 10px solid rgba(255, 139, 9, 1);border-bottom: 10px solid rgba(255, 139, 9, 1);}50% {border-top: 10px solid rgba(253, 87, 17, 1);border-bottom: 10px solid rgba(253, 87, 17, 1);}100% {border-top: 10px solid rgba(255, 139, 9, 1);border-bottom: 10px solid rgba(255, 139, 9, 1);}}@-ms-keyframes preloader_1 {0% {-ms-transform: rotate(0deg);}50% {-ms-transform: rotate(180deg);background: #ff4f11;}100% {-ms-transform: rotate(360deg);}}@-ms-keyframes preloader_1_after {0% {border-top: 10px solid rgba(255, 139, 9, 1);border-bottom: 10px solid rgba(255, 139, 9, 1);}50% {border-top: 10px solid rgba(253, 87, 17, 1);border-bottom: 10px solid rgba(253, 87, 17, 1);}100% {border-top: 10px solid rgba(255, 139, 9, 1);border-bottom: 10px solid rgba(255, 139, 9, 1);}}@keyframes preloader_1 {0% {transform: rotate(0deg);}50% {transform: rotate(180deg);background: #ff4f11;}100% {transform: rotate(360deg);}}@keyframes preloader_1_after {0% {border-top: 10px solid rgba(255, 139, 9, 1);border-bottom: 10px solid rgba(255, 139, 9, 1);}50% {border-top: 10px solid rgba(253, 87, 17, 1);border-bottom: 10px solid rgba(253, 87, 17, 1);}100% {border-top: 10px solid rgba(255, 139, 9, 1);border-bottom: 10px solid rgba(255, 139, 9, 1);}}</style></head><script>function getPara(name) {var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");var r = window.location.search.substr(1).match(reg);if (r != null) {return unescape(r[2]);}return null;}let uid = getPara("uid");let msg = getPara("msg");if (msg) {localStorage.setItem("_mpmsg_", JSON.stringify([uid, msg]));}</script><body><div id="loadingBg"><div id="preloader"></div><!-- <div>加载中</div> --></div></body>
</html>

http://www.ppmy.cn/ops/141251.html

相关文章

【1】Python交叉编译到OpenHarmony标准系统运行(arm32位)

本文介绍如何Python语言如何在OpenHarmony标准系统运行,包括5.0r和4.1r以及4.0r,和未来版本的OpenHarmony版本上。 Python语言在OpenHarmony上使用,需要将Python解释器CPython移植到OpenHarmony标准系统。通过交叉编译的方式。 首先来了解几个概念: CPython 是 Python 编…

22.在Vue3中使用OpenLayers加载远程 KML 文件示例

前言 OpenLayers 是一个功能强大的开源地图库&#xff0c;广泛应用于前端 GIS&#xff08;地理信息系统&#xff09;开发中。 而 KML&#xff08;Keyhole Markup Language&#xff09;是一种用于表示地理空间数据的标准文件格式&#xff0c;通常用于存储点、线、多边形等地理要…

单片机:实现生日快乐歌(附带源码)

单片机实现《生日快乐歌》 实现一个“生日快乐歌”是单片机应用中的一个经典项目&#xff0c;通过它可以学习如何控制声音输出、使用定时器、以及如何处理按键输入等功能。本项目将利用单片机生成《生日快乐歌》的音频信号&#xff0c;并通过蜂鸣器播放出来。 项目目标 本项…

自然语言处理:从入门到精通全指引

一、引言 自然语言处理&#xff08;NLP&#xff09;作为人工智能领域的关键分支&#xff0c;旨在让计算机理解、生成和处理人类语言&#xff0c;近年来取得了令人瞩目的成就&#xff0c;在智能客服、机器翻译、文本分析、语音助手等众多领域发挥着重要作用。从入门到精通自然语…

java中的数组(3)

大家好&#xff0c;今天给大家继续讲解数组这部分内容&#xff0c;有助于大家对数组的理解更深&#xff0c;那么我们就来看看接下来的内容。 4.认识.null int[] array null;(代表这个引用不指向任何对系) System. out.println (array); array [0] 1; err. NulLPointer …

前端文件下载

这里写自定义目录标题 前端文件下载方法使用a标签使用iframe标签二进制流 前端文件下载方法 使用a标签 /*** 文件下载方法 使用a标签* 存在浏览器下载时&#xff0c;太快的话&#xff0c;会取消上次的下载请求* param {*} href* param {*} filename*/ export function downlo…

Github 2024-12-11C开源项目日报Top10

根据Github Trendings的统计,今日(2024-12-11统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量C项目10Netdata: 开源实时监控平台 创建周期:4020 天开发语言:C协议类型:GNU General Public License v3.0Star数量:68982 个Fork数量:577…

力扣第95题 不同的二叉搜索树 II

不同的二叉搜索树 II 一级目录二级目录三级目录 力扣第95题 - 不同的二叉搜索树 II题目描述思路分析1. 二叉搜索树的性质2. 递归构造树3. 动态规划优化&#xff08;可选&#xff09; 递归详细递归函数定义参数含义返回值 递归的逻辑递归过程的可视化第一次递归&#xff08;范围…