question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[WebView] onMessage failing when there are JS warnings and errors on the page

See original GitHub issue

Description

I’m receiving this error (same as screenshot below):

Setting onMessage on a WebView overrides existing values of window.postMessage, 
but a previous value was defined.

screen shot 2016-11-10 at 3 33 31 pm

That specific error message is found in the code base here: https://github.com/facebook/react-native/blob/master/React/Views/RCTWebView.m#L286

Implementation

I followed the example at this link for onMessage at this link: http://facebook.github.io/react-native/releases/0.37/docs/webview.html#examples

I made a callable respondToOnMessage and injected some JavaScript.

class MessagingTest extends React.Component {

    respondToOnMessage = e =>{
        console.log(e);
    };

    render() {
        const jsCode = `window.postMessage('test');`;

        return (
        <WebView
        injectedJavaScript={jsCode}
        source={uri: 'https://www.foo.com/'}}
        onMessage={this.respondToOnMessage}
        />
        )
    }
}

Reproduction

I load the app with this example and I have it pointed to a website (rather not say which one. Sorry.) And the website is emitting 2 errors into the Chrome console when I go there.

(index):994 A Parser-blocking, cross-origin script, http://example.com/thing.js, is invoked via document.write. This may be blocked by the browser if the device has poor network connectivity.

widgets.js:8 Uncaught TypeError: Cannot set property '[object Array]' of undefined(…)

Other websites like google.com and github.com are just fine. If you want to replicate it, change the uri to yahoo.com

Additional Information

  • React Native version: 0.37
  • Platform: iOS 10.1, iPhone 6 emulator
  • Operating System: Mac OSX Sierra 10.12.1

Issue Analytics

  • State:closed
  • Created 7 years ago
  • Reactions:84
  • Comments:92 (7 by maintainers)

github_iconTop GitHub Comments

255reactions
kyle-ilantziscommented, Dec 31, 2016

injectedJavascript should instead be the following

(function() {
  var originalPostMessage = window.postMessage;

  var patchedPostMessage = function(message, targetOrigin, transfer) { 
    originalPostMessage(message, targetOrigin, transfer);
  };

  patchedPostMessage.toString = function() { 
    return String(Object.hasOwnProperty).replace('hasOwnProperty', 'postMessage'); 
  };

  window.postMessage = patchedPostMessage;
})();

And then it works! 😄

And if any one is interested, in my code instead of writing a giant string I did the following

const patchPostMessageFunction = function() {
  var originalPostMessage = window.postMessage;

  var patchedPostMessage = function(message, targetOrigin, transfer) { 
    originalPostMessage(message, targetOrigin, transfer);
  };

  patchedPostMessage.toString = function() { 
    return String(Object.hasOwnProperty).replace('hasOwnProperty', 'postMessage');
  };

  window.postMessage = patchedPostMessage;
};

const patchPostMessageJsCode = '(' + String(patchPostMessageFunction) + ')();';

...

<WebView injectedJavaScript={patchPostMessageJsCode} />
37reactions
MrLohcommented, Jun 12, 2017

the solution from @kyle-ilantzis works well. I just wrote a patched WebView class for myself, feel free to use. This class also automatically JSON encodes and decodes the messages and tweaked the source attribute to my liking.

import React from 'react'
import { WebView } from 'react-native'

// fix https://github.com/facebook/react-native/issues/10865
const patchPostMessageJsCode = `(${String(function() {
    var originalPostMessage = window.postMessage
    var patchedPostMessage = function(message, targetOrigin, transfer) {
        originalPostMessage(message, targetOrigin, transfer)
    }
    patchedPostMessage.toString = function() {
        return String(Object.hasOwnProperty).replace('hasOwnProperty', 'postMessage')
    }
    window.postMessage = patchedPostMessage
})})();`

export default class MessageWebView extends React.Component {
    constructor(props) {
        super(props)
        this.postMessage = this.postMessage.bind(this)
    }
    postMessage(action) {
        this.WebView.postMessage(JSON.stringify(action))
    }
    render() {
        const { html, source, url, onMessage, ...props } = this.props
        return (
            <WebView
                {...props}
                javaScriptEnabled
                injectedJavaScript={patchPostMessageJsCode}
                source={source ? source : html ? { html } : url}
                ref={x => {this.WebView = x}}
                onMessage={e => onMessage(JSON.parse(e.nativeEvent.data))}
            />
        )
    }
}
Read more comments on GitHub >

github_iconTop Results From Across the Web

React Native WebView postMessage does not work
IN JS side - window.WebViewBridge = { onMessage: this._onMessage, }; const event = new Event('WebViewBridge'); window.
Read more >
React Native WebView PostMessage 问题 - Phodal
这次就机智了,第一时间找React Native 官网的issues,果然就有了:onMessage failing when there are JS warnings and errors on the page.
Read more >
WebView · React Native
Security Warning: Currently, onMessage and postMessage do not allow specifying an origin. This can lead to cross-site scripting attacks if an unexpected ...
Read more >
webview-onmessage - Expo Snack
Did you know: You can turn off automatic updates under Devices in the footer? Minified React error #130; visit https://reactjs.org/docs/error-decoder.html?
Read more >
React Native Webview Onmessage Is Not Triggered - ADocLib
[WebView] onMessage failing when there are JS warnings and errors on the page #10865 postMessage not working in iOS release build #20226. log'Data...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found