我无法让React Native WebView postMessage工作。 React Native应用程序成功从Web应用程序接收post message messaget。但是,Web应用程序不会从React Native应用程序接收消息发送。
我简单的网络应用
<html>
<body>
<button>Send post message from web</button>
<div>Post message log</div>
<textarea style="height: 50%; width: 100%;" readonly></textarea>
<script>
var log = document.querySelector("textarea");
document.querySelector("button").onclick = function() {
console.log("Send post message");
logMessage("Sending post message from web..");
window.postMessage("Post message from web", "*");
}
window.addEventListener("message", function(event) {
console.log("Received post message", event);
logMessage(event.data);
}, false);
function logMessage(message) {
log.append((new Date()) + " " + message + "\n");
}
</script>
</body>
</html>
此网络应用程序位于:https://popping-heat-6062.firebaseapp.com/
我简单的React Native应用
import React, {Component} from "react";
import {AppRegistry, Text, View, TouchableHighlight, WebView} from "react-native";
export default class WevViewApp extends Component {
constructor( props ) {
super( props );
this.webView = null;
}
onMessage( event ) {
console.log( "On Message", event.nativeEvent.data );
}
sendPostMessage() {
console.log( "Sending post message" );
this.webView.postMessage( "Post message from react native" );
}
render() {
return (
<View style={{flex: 1}}>
<TouchableHighlight style={{padding: 10, backgroundColor: 'blue', marginTop: 20}} onPress={() => this.sendPostMessage()}>
<Text style={{color: 'white'}}>Send post message from react native</Text>
</TouchableHighlight>
<WebView
style={{flex: 1}}
source={{uri: 'https://popping-heat-6062.firebaseapp.com'}}
ref={( webView ) => this.webView = webView}
onMessage={this.onMessage}
/>
</View>
);
}
}
AppRegistry.registerComponent( 'WevViewApp', () => WevViewApp );
预期结果
实际结果
有谁知道为什么网络应用没有收到消息?
使用Android和iOS进行测试。
相关文档:https://facebook.github.io/react-native/docs/webview.html
修改:遇到可能查明问题的行为。
当直接在网络浏览器中测试“从网上发送帖子”按钮时,textarea会记录它已发送消息,并且还会收到消息。
Thu Dec 15 2016 10:20:34 GMT+0100 (CET) Sending post message from web..
Thu Dec 15 2016 10:20:34 GMT+0100 (CET) Post message from web
在React Native应用程序的WebView中尝试相同时,textarea只打印出
Thu Dec 15 2016 10:20:34 GMT+0100 (CET) Sending post message from web..
WebView是否劫持了window.postMessage方法并注入了自定义方法?
中提到了这一点设置此属性会将postMessage全局注入您的 webview,但仍然会调用postMessage的预先存在的值。
也许这是错误的,这就是问题所在?
答案 0 :(得分:42)
我遇到了同样的问题并通过将事件监听器添加到文档而不是窗口来修复它。变化:
window.addEventListener("message", ...
为:
document.addEventListener("message", ...
答案 1 :(得分:3)
react-native-webview changes how this behavior works的版本5。您现在想要:
window.ReactNativeWebView.postMessage(data);
答案 2 :(得分:2)
在Android系统中
nil
在iOS中
document.addEventListener("message", function(event) {
alert("This is a Entry Point Working in android");
init(event.data)
});
答案 3 :(得分:0)
实际上,侦听器在不同的操作系统(例如iOS和Android)中的工作方式有所不同。因此,对于Android,应使用document.addEventListener;对于iOS,应使用window.addEventListener。
if(navigator.appVersion.includes('Android')){
document.addEventListener("message", function (data) {
alert("you are in android OS");
});
}
else {
window.addEventListener("message", function (data) {
alert("you are in android OS");
});
}
答案 4 :(得分:0)
以上答案均不适用于 IOS,可能仍适用于 android 设备。这种方式适用于所有平台 -
在本机反应中:
const generateOnMessageFunction = data =>
`(function() {
window.WebViewBridge.onMessage(${JSON.stringify(data)});
})()`;
class RNScreen extends React.Component{
private webView: RefObject<WebView> = createRef();
render(){
return (
<WebView
javaScriptEnabled
domStorageEnabled
bounces={false}
ref={this.webView}
onLoadEnd={() => {
this.postMessageTest({helloFromRN: true});
}}
/>
)
}
private postMessageTest(data){
this.webView.current.injectJavaScript(generateOnMessageFunction(data));
}
}
在 JS 端 -
window.WebViewBridge = {
onMessage: this._onMessage,
};
const event = new Event('WebViewBridge');
window.dispatchEvent(event);
// The data is not a string. It is an object.
private _onMessage(data: Object){
// Should log "helloFromRN" on load.
console.log(data)
}
答案 5 :(得分:0)
您可以按照以下步骤进行发布/订阅 =>>
步骤 1 => 在您的本机应用程序中添加插件: https://github.com/react-native-webview/react-native-webview
第 2 步 => 在 ReactNative(Mobile Part) 中添加以下代码:
import React, { Component } from "react";
import { SafeAreaView, Text, TouchableHighlight } from "react-native";
import { WebView } from "react-native-webview";
class MobileWebView extends Component {
state = {};
onMessage = event => {
const { data } = event.nativeEvent;
this.setState({ data });
};
render() {
return (
<SafeAreaView style={{ flex: 1 }}>
<TouchableHighlight
style={{
padding: 10,
backgroundColor: "red",
width: "100%",
}}
onPress={() => {
this.webview.postMessage("Message From React Native App to Web");
}}
>
<Text>Send Message To Web</Text>
</TouchableHighlight>
<Text>Mobile: {this.state.data}</Text>
<WebView
ref={ref => {
this.webview = ref;
}}
source={{ uri: "http://localhost:3000/" }}
onMessage={this.onMessage}
style={{ flex: 1 }}
/>
</SafeAreaView>
);
}
}
export default MobileWebView;
步骤 3 => 在 ReactJS(Web Part) 中添加以下代码:
import React, { Component } from "react";
class WebApp extends Component {
state = {};
componentDidMount() {
document.addEventListener("message", event => {
this.setState({ msg: event.data });
});
window.addEventListener("message", event => {
this.setState({ msg: event.data });
});
}
render() {
return (
<div>
<div>Web: {this.state.msg}</div>
<button
onClick={() => {
window.ReactNativeWebView.postMessage(
"Post message from web to Mobile",
"*"
);
}}
>
Send Message To React Native(Mobile)
</button>
</div>
);
}
}
export default WebApp;
一切顺利,现在您可以从移动设备到 Web 发送和接收消息,反之亦然。