React Native WebView postMessage不起作用

Ska*_*rbo 21 javascript html5 webview react-native

我无法让React Native WebView postMessage工作.React Native应用程序成功从Web应用程序接收post message messaget.但是,Web应用程序不会从React Native应用程序接收消息sendt.

我简单的网络应用

<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>
Run Code Online (Sandbox Code Playgroud)

此Web应用程序托管在: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 );
Run Code Online (Sandbox Code Playgroud)

预期结果

  1. 单击"从Web发送消息"按钮会将消息发送到React Native应用程序并记录在调试器窗口中
  2. 单击"从React Native发送帖子消息"按钮会将一条帖子消息发送到Web应用程序并打印在Web textarea中

实际结果

  1. Web应用程序成功将发送消息发送到React Native应用程序并记录在调试器窗口中
  2. React Native应用程序未成功将消息发送到Web应用程序,并且未在Web textarea中打印出来

有谁知道为什么网络应用程序没有收到消息?

经过Android和iOS测试.

相关文档:https://facebook.github.io/react-native/docs/webview.html


编辑:经历过可能查明问题的行为.

当直接在Web浏览器中测试"从Web发送消息"按钮时,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
Run Code Online (Sandbox Code Playgroud)

当从React Native应用程序在WebView中尝试相同时,textarea只打印出来

Thu Dec 15 2016 10:20:34 GMT+0100 (CET) Sending post message from web..
Run Code Online (Sandbox Code Playgroud)

WebView是否劫持了window.postMessage方法并注入了一个自定义方法?

这在文档中提到:

设置此属性会将postMessage全局注入到您的webview中,但仍会调用postMessage的预先存在的值.

也许这是错误的,这就是问题所在?

Jus*_*der 49

我遇到了同样的问题,并通过将事件监听器添加到文档而不是窗口来修复它.更改:

window.addEventListener("message", ...
Run Code Online (Sandbox Code Playgroud)

至:

document.addEventListener("message", ...
Run Code Online (Sandbox Code Playgroud)

  • 这有效.谢谢.记住,如果你也想支持常规浏览器,你应该定义`document.addEventListener("message",...`和`window.addEventListener("message",...`.). (2认同)
  • 任何人都能解释一下吗? (2认同)

Ada*_*amG 24

react-native-webview的版本5 更改了此行为的工作方式。您现在想要:

window.ReactNativeWebView.postMessage(data);
Run Code Online (Sandbox Code Playgroud)


Kes*_*era 7

添加浏览器特定的事件侦听器

在安卓中

 document.addEventListener("message", function(event) {
       alert("This is a Entry Point Working in Android");
       init(event.data)
  });
Run Code Online (Sandbox Code Playgroud)

在 iOS 中

 window.addEventListener("message", function(event) {
       alert("This is a Entry Point Working in iOS");
       init(event.data)
  });
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明


nir*_*jan 5

实际上,监听器在不同的操作系统(例如 iOS 和 Android)中的工作方式有所不同。document.addEventListener因此,您应该在 Android 和window.addEventListeneriOS 上使用。

if (navigator.appVersion.includes('Android')) {
  document.addEventListener("message", function (data) {
    alert("you are in iOS");
  });
}
else {
  window.addEventListener("message", function (data) {
    alert("you are in android OS");
  });
}
Run Code Online (Sandbox Code Playgroud)