Я нашел эффективный способ передачи данных из мини-программы в содержимое веб-просмотра, и кажется, что на данный момент это единственно возможный способ сделать это.
Мини-программа
1. Модуль Base64
Вам нужно будет иметь возможность конвертировать обычную строку в строку 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-view
подготовьте элемент DOM в файле wxml
следующим образом:
Файл: 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
— это массив, в котором будут храниться ожидающие сообщения для отправки в веб-представление. messageQueueSize
- это просто длина массива. Используется для повышения производительности, чтобы избежать чтения Array.length.
3. Запустить очередь сообщений
В onShow
обратном вызове страницы установите webURL
и запустите интервал, который будет читать messageQueue
массив каждые 250 мс. Вы можете изменить способ, которым это делается, если вам не нравятся интервалы, это был просто самый простой способ проверить теорию.
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);
}
Вы можете видеть, что сообщение добавляется к источнику веб-просмотра (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++;
}
Всякий раз, когда вы вызываете этот метод, просто передайте объект с любыми свойствами, которые вам нужны, и он будет преобразован в строку JSON, затем в строку base64 и, наконец, добавлен в очередь сообщений.
Свойство unique
добавлено, чтобы сгенерированный результат base64 всегда отличался, даже если остальные свойства объекта одинаковы - мне это просто нужно для целей моего проекта. Вы можете игнорировать его/удалить, если он вам не нужен.
Поскольку существует интервал выполнения и проверки очереди сообщений, все сообщения, добавленные таким образом, будут отправлены в веб-представление в том же порядке, в котором они были добавлены в очередь.
Теперь осталось только одно — добавить прослушивание изменения хэша в HTML-странице, которую мы загрузили в веб-представление:
HTML-веб-приложение
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. Мне еще предстоит проверить на других устройствах, продаваемых в Китае.
Ваше здоровье!
person
Sinisa
schedule
23.06.2019