将消息从微信小程序发送到网络视图

时间:2019-06-16 15:47:14

标签: javascript webview wechat

我正在构建微信小程序,该程序的其中一个页面具有web-view控件。例如:

page.wxml

<web-view src="https://..." bindmessage="onWebViewMessage"></web-view>

page.js

const app = getApp();
Page({
    onWebViewMessage:function(e) {
         console.log(e);
    },
    onLoad:function() {
    }
});

web-view中,将加载一个HTML页面(index.html),其中包括来自WeChat的jweixin-1.3.2.js lib,用于与WeChat API连接以及与父小程序连接。页面为空,没有DOM元素,只有加载文档时将执行的javascript。

它具有像这样的javascript:

index.js

document.addEventListener('DOMContentLoaded',function(){
    wx.miniProgram.postMessage({data:'test'});
});

我能够将文档中的消息发布到小型程序中,而不会出现问题。还可以发送一些小程序导航命令,例如wx.miniProgram.navigateTo({url:'path/to/page'});,所以一切似乎都很好。 web-view完成加载后,我还可以在小型程序中获得回调。

问题:

如何从小程序中将消息 发布到网络视图?例如,将字符串或对象传递到Web视图。

我已经搜寻了几个小时,似乎找不到任何人这样做,但是我不敢相信这只是一种单向的沟通。

任何帮助或想法都会受到赞赏!

1 个答案:

答案 0 :(得分:0)

我已经找到了一种将数据从小程序传递到Web视图内容的有效方法,而且目前看来,这是唯一可行的方法。

小程序

1。 Base64模块

您将需要能够将普通String转换为Base64字符串。小型程序API具有将字节数组转换为base64字符串的方法,但是不能用于此目的。因此,创建您自己的模块来完成该任务:

文件:lib/b64.js

var string2base64 = function(str) {
    .... here put your js code for making b64 string ....
    return result;
};

module.exports = {
    string2base64
};

2。具有Web视图的页面

在具有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对象中,添加webURLwebBaseURL属性,如下所示:

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。

3。启动消息队列

在页面的onShow回调中,设置webURL并开始间隔,该间隔将每250ms读取一次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,然后将其发送到网络视图。

4。将消息添加到队列中

要在消息队列中创建消息,只需在页面中定义以下方法:

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++;
}

无论何时调用此方法,只需传递一个具有所需属性的Object,它将转换为JSON字符串,然后转换为base64字符串,最后附加到消息队列中。

添加了

unique属性,以使生成的base64结果始终不同,即使其余对象属性都相同-我只是出于项目目的而已。您可以忽略它,或者在不需要它时将其删除。

由于在消息队列上运行并检查间隔,所有这样添加的消息将按照添加到队列的顺序发送到Web视图。

现在只剩下一件事了-在我们已加载到网络视图的HTML页面中添加哈希更改侦听:

HTML Web应用

1。听哈希变化

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);
});

在Xiaomi Mi8 Pro上测试。我尚未在中国销售的其他设备上进行测试。

干杯!