[英]Send message from WeChat mini-program to web-view
我正在构建微信小程序,它的一个页面上有web-view
控件。 例如:
页面.wxml
<web-view src="https://..." bindmessage="onWebViewMessage"></web-view>
页面.js
const app = getApp();
Page({
onWebViewMessage:function(e) {
console.log(e);
},
onLoad:function() {
}
});
在web-view
中加载一个 HTML 页面(index.html),其中包含来自微信的jweixin-1.3.2.js
库,用于连接微信 API 以及连接到父小程序。 页面为空,没有 DOM 元素,只有在加载文档时执行的 javascript。
它的 javascript 是这样的:
索引.js
document.addEventListener('DOMContentLoaded',function(){
wx.miniProgram.postMessage({data:'test'});
});
我可以毫无问题地将此文档中的消息发布到小程序。 也可以发送一些小程序导航命令如wx.miniProgram.navigateTo({url:'path/to/page'});
所以一切似乎都很好。 当web-view
加载完成时,我也可以在小程序中获得回调。
题:
如何从小程序发布消息到网页视图? 例如,将字符串或对象传递给 web 视图。
我已经在谷歌上搜索了几个小时,似乎找不到任何人在做这件事,但我不敢相信这只是一种可能的单向交流。
任何帮助或想法表示赞赏!
我找到了一种将数据从小程序传递到网络视图内容的有效方法,目前看来,这是唯一可行的方法。
您需要能够将普通字符串转换为 Base64 字符串。 小程序 API 有一种将字节数组转换为 base64 字符串的方法,但不能用于此目的。 因此,创建您自己的模块来执行此操作:
文件: lib/b64.js
var string2base64 = function(str) {
.... here put your js code for making b64 string ....
return result;
};
module.exports = {
string2base64
};
在具有web-view
控件的页面中,像这样在wxml
文件中准备 DOM 元素:
文件: pages/xxx/index.wxml
<web-view src="{{webURL}}" bindload="onWebLoad" binderror="onWebError"></web-view>
请注意, src
参数现在绑定到页面的webURL
属性。 每当页面为此属性设置值时,将自动应用于 DOM 元素。
在文件pages/xxx/index.js
您需要添加 base64 模块:
const b64 = require('../../lib/b64.js')
请注意,需要路径可能会有所不同,具体取决于您设置项目的方式
并在页面的data
对象中,添加webURL
和webBaseURL
属性,如下所示:
Page({
data: {
webURL:'',
webBaseURL:'https://your/web/app/url',
messageQueue:[],
messageQueueSize:0,
.... other page properties go here ....
},
..... rest of your page code goes here .....
})
请注意, webURL
设置为空。 这意味着当页面加载时,默认情况下会为 DOM 对象设置一个空字符串。
webBaseURL
将解释一下。
messageQueue
是一个数组,用于存储要发送到 web 视图的待处理消息。 messageQueueSize
只是数组长度。 用于更好的性能,以避免读取 Array.length。
在页面的onShow
回调中,设置webURL
和每webURL
读取一次messageQueue
数组的启动间隔。 如果您不喜欢使用间隔,您可以更改这样做的方式,这只是进行理论测试的最简单方法。
onShow: function(){
// This will start loading of the content in web-view
this.setData({webURL: this.data.webBaseURL } );
// Sends message from message queue to web-view
let _this = this;
setInterval(function(e) {
if( _this.data.messageQueueSize < 1 ) return;
_this.data.messageQueueSize --;
let msg = _this.data.messageQueue.splice(0,1);
_this.setData({webURL: _this.data.webBaseURL+"#"+msg});
},250);
}
您可以看到该消息作为哈希附加到 web 视图源 (url)。
webBaseURL
用于生成带有哈希的最终 URL,然后将其发送到 web-view。
要在消息队列中创建消息,只需在页面中定义以下方法:
addMessageToQueue: function(obj) {
obj.unique = Math.round(Math.random()*100000);
let msg = b64.string2base64(JSON.stringify(obj));
this.data.messageQueue.push(msg);
this.data.messageQueueSize++;
}
无论何时调用此方法,只需传递一个具有您需要的任何属性的对象,它将被转换为 JSON 字符串,然后转换为 base64 字符串,最后附加到消息队列中。
添加unique
属性以使生成的 base64 结果始终不同,即使其余对象属性相同 - 我只是为了我的项目需要这个。 如果您不需要它,您可以忽略它/删除它。
由于有间隔运行和检查消息队列,所有像这样添加的消息将按照它们添加到队列的相同顺序发送到 web-view。
现在只剩下一件事了 - 在我们加载到 web 视图的 HTML 页面中添加哈希更改监听:
window.addEventListener("hashchange",function(e){
let messageBase64 = window.location.hash.substr(1);
let json = window.atob( messageBase64 );
let data = JSON.parse(json);
console.log("Received data from mini-program:",data);
});
在小米8 Pro上测试。 我尚未在中国销售的其他设备上进行测试。
干杯!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.