依据
在webview内部的网页中调用window.postMessage方法时可以触发此属性对应的函数,从而实现网页和RN之间的数据交换。 设置此属性的同时会在webview中注入一个postMessage的全局函数并覆盖可能已经存在的同名实现。
网页端的window.postMessage只发送一个参数data,此参数封装在RN端的event对象中,即event.nativeEvent.data。data 只能是一个字符串。
在React Native 0.37版本中,合并入了react-native-webview-bridge作者的某个PR,从此React Native中自带的WebView拥有了和Web通信的功能。此版本之前的版本也可以用react-native-webview-bridge或者其他WebView Bridge的方案进行通信。
所需工具
- react-native版本>=0.37(必须)
- react-native-document-picker(用于调用系统文件选择框)
- react-native-fs(把文件转为base64字符串)
步骤
- 安装react-native-document-picker和react-native-fs
npm install react-native-fs --save
npm i --save react-native-document-picker
react-native link
- web端
//第一步
$(element).click(function () {
var $fileName = $(element).attr('fileName');
var $fileId = $(element).attr('fileId');
var jsonObj = {};//构造与react-native端通信的对象
jsonObj.type = 'file';
jsonObj.id = $fileId;
jsonObj.name=$fileName;
var jsonString = JSON.stringify(jsonObj);
window.postMessage(jsonString,'*');
//主要:window.postMessage()
});
//第二步
window.document.addEventListener('message',function (e) {
//接收从react-native端返回的数据,并进行处理
//e.data则是react-native返回的数据
}
- react-native端
onMessageChange(event) {
let messageString = event.nativeEvent.data;
let obj = JSON.parse(messageString)
if (obj.type == 'file') {
//调用文件选择框,打开系统文件选择
DocumentPicker.show({
filetype: [DocumentPickerUtil.allFiles()],
}, (error, res) => {
console.log(res);
if (res != null) {
let filePath = res.uri;
let fileType = res.type;
let fileName = res.fileName;
let fileSize = res.fileSize;
//把文件转换成base64字符串
RNFetchBlob.fs.readFile(filePath, 'base64')
.then((data) => {
console.log(data);
let message = {};
message.command = 'file';
message.fileName = fileName;
message.fileType = fileType;
message.id = obj.id;
message.name = obj.name;
message.playload = { uri: data };
let messageString = JSON.stringify(message);
//webview像web端传递数据
this.webview.postMessage(messageString);
});
}
});
}
}