react-native: [WebView] onMessage failing when there are JS warnings and errors on the page
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.
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
About this issue
- Original URL
- State: closed
- Created 8 years ago
- Reactions: 84
- Comments: 92 (7 by maintainers)
Links to this issue
Commits related to this issue
- patchedPostMessageJsCode injected in Webview Due to the React Native's webview error(saying that window.postMessage is overridden), the workaround has suggested in the github issue(https://github.com... — committed to iamport/iamport-react-native by hyukkwonepic 7 years ago
- Remove spinner (due it's hangs on second chat open) add window.postMessage padding due RN issue https://github.com/facebook/react-native/issues/10865 — committed to AllmaxTeam/react-native-intercom-webview by zloybest 7 years ago
- Fix native postMessage test The current way we're testing if postMessage has been changed is no longer valid. Lodash has already changed the way they test agianst this, as it no longer works in blink... — committed to ivank/react-native by ivank 6 years ago
- Fix native postMessage test The current way we're testing if postMessage has been changed is no longer valid. Lodash has already changed the way they test agianst this, as it no longer works in blink... — committed to ivank/react-native by ivank 6 years ago
- Fix native postMessage test The current way we're testing if postMessage has been changed is no longer valid. Lodash has already changed the way they test agianst this, as it no longer works in blink... — committed to ivank/react-native by ivank 6 years ago
- Fix native postMessage test The current way we're testing if postMessage has been changed is no longer valid. Lodash has already changed the way they test agianst this, as it no longer works in blink... — committed to ivank/react-native by ivank 6 years ago
- Fix native postMessage test The current way we're testing if postMessage has been changed is no longer valid. Lodash has already changed the way they test agianst this, as it no longer works in blink... — committed to ivank/react-native by ivank 6 years ago
- Fix native postMessage test The current way we're testing if postMessage has been changed is no longer valid. Lodash has already changed the way they test agianst this, as it no longer works in blink... — committed to ivank/react-native by ivank 6 years ago
- iOS specific workaround - https://github.com/facebook/react-native/issues/10865#issuecomment-269847703 — committed to addonslab/react-native-autoheight-webview by harutyundr 5 years ago
injectedJavascript should instead be the following
And then it works! 😄
And if any one is interested, in my code instead of writing a giant string I did the following
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.
Please keep this open. It is very real.
+1 getting the same error.
It’s because the page you’re visiting is overriding
postMessage
, which may be due to a shim. Showing an error was chosen over invoking the shim’s value ofpostMessage
when you call the value ofpostMessage
that we set.I thought I’d made it easier to workaround this problem, but it looks like that won’t work. The best you can do at the moment, which is an awful hack, is,
Or just fork the project and remove the code you pointed to. Whatever’s easiest for you!
Ping @satya164 for input on how to resolve.
Hi there! This issue is being closed because it has been inactive for a while. Maybe the issue has been fixed in a recent release, or perhaps it is not affecting a lot of people. Either way, we’re automatically closing issues after a period of inactivity. Please do not take it personally!
If you think this issue should definitely remain open, please let us know. The following information is helpful when it comes to determining if the issue should be re-opened:
If you would like to work on a patch to fix the issue, contributions are very welcome! Read through the contribution guide, and feel free to hop into #react-native if you need help planning your contribution.
please see http://68xg.com/reactnative/82.html
I found workaround that works for me (RN 0.52)
Just add at the end of the
injectedScript
You could wait for the
onLoad
before passingonMessage
into the component (passingnull
until the onLoad triggers).It worked for us, but we had to implement a simple queue in the webview that collects posts until the
onLoad
has triggered, which then triggers anotheronLoad
inside the webview usinginjectJavaScript
…For me it helped to use ‘useWebKit’ prop on a WebView.
What @MrLoh said, this issue is very real, please keep it open.
If you feel brave, use a shell script to rename the native
postMessage
:After running this script (you will need to do it after each
yarn
npm install
), you can simply use:inside your webView. IMO, this should be done a long time ago… there is a PR here for basically the same thing: https://github.com/facebook/react-native/pull/12997/files?diff=split
+1, I’m getting the same error. When there is a
iframe
on web, it occurs the same errorRe-opening. Is anyone working on a fix or is there a PR waiting for review? I want to make sure this gets fixed before the issue gets closed due to inactivity.
Absolutely still a problem over here too. Please keep open @hramos
Injecting a patched
postMessage
method did not work for me (RN 0.55, macOS 10.13, iOS). In my case the error only occurred when I rendered aniframe
(React
+ReactDOM
) inside my WebView.This issue will not occur is you use “useWebKit” prop of webview, that will use WK webview instead of UI webview in case of IOS. But in case if you don’t want to use WK webview, then below is the sample JS code that you can inject in you Webview with “injectedJavaScript” prop.
The above code did nothing just patched window.postMessage function, the above issue will not appear.
Hi there, we are migrating all the WebView issues to the new repository https://github.com/react-native-community/react-native-webview. Correct me if I’m wrong but this does not seem to happen with the new WKWebview implementation. If it does, feel free to open an issue directly on the new repository and link that issue to it! Thanks,
Yes we know there are workarounds documented here. But it’s still a bug nevertheless.
Please keep open.
While this proplem is real and it should be open. We worked around this problem using https://github.com/CRAlpha/react-native-wkwebview, but sadly this means we have two different implementations of the code injected for iOS and android. It would be much nicer too have a solution working the same on both platforms with the default WebView
I tried @MrLoh’s Code, but I still get the red error screen:
package.json
I have same error, without injecting any javascript to WebView - just setting WebView-properties:
source={require(‘…/lib/html/somefile.html’)} onMessage={() => console.log(‘Hello World’)}
and in my …/lib/html/somefile.html’ I have javascript code doing both window.postMessage() and document.addEventListener(“message”,…
Everything worked fine when I had the HTML in a variable “someHtml”, like: source={{html: someHtml}}
So difference seem to be when changing source to HTML-file instead of HTML-string.
Still for me I had other reasons, not related to this, why I really need to read HTML from file instead of string so it would be great to get this issue fixed.
Oh I see. The JS is injected after postMessage is overwritten. Your best bet is to fork it then, and I’ll see what I can do about getting this fixed! Sorry. 😦
Try
injectedJavaScript="window.RNPostMessage = window.postMessage;window.postMessage = String(Object.hasOwnProperty).replace('hasOwnProperty', 'postMessage');"
Then use
window.RNPostMessag
Same issue with this versions: “react”: “16.3.2”, “react-native”: “0.55.4”,
Here some example code for sending and receiving messages from react native and web view back and fourth.
native side:
webview side:
In my project this red screen doesn’t appear for non-debug build and the web page I’m using still works without any issue. While in debug build I could just dismiss the red screen and continue. But It’s kinda annoying and who knows when an issue’s gonna popping up in non-debug build. Please fix.
+1,encounter this problem
+1, still has this problem
For anyone still struggling with this, I released rn-webview on NPM to solve this exact problem (open-sourced on GitHub). My team and myself are unable or unwilling to eject from our Expo implementation in order to use the community edition linked a few posts above. If you are able to do so, I’d recommend that option. If you want to maintain a purely JavaScript, out-of-the-box Expo experience, the rn-webview package is for you.
I wrote a walkthrough for how it works on Medium. Of course the implementation has to have drawbacks, and the way it works may not be acceptable for your use case. The biggest deal is that, instead of relying on native
window.postMessage
function, it instead manipulates the history (history.pushState
) so that it can listen to the navigation state change event (which is supported by both Android and iOS). Feel free to suggest better implementations in the Issues for the repo or fork and adjust not altering the navigation state is crucial to your project.Hope this helps!
#12997 will not necessarily fix this. I fixed it locally and submitted a pull request #16502 I also created a gist for a quick fix for react native 0.44.2 here
still not working, on rn - 0.48.4 stills shows a red screen error
@kyle-ilantzis Yeah. Now I have huge problem because docs cause red screen and your solution helps with the red screen but block
webview.postMessage
- no idea what to do 😉Is this by any chance solved in a newer version of react-native ? Or is this just laying out here for about half year?
@skrobek Oh no 😱
My objective was to have the JS code in the webview talk to react-native. It was not to have react-native talk to itself through a webview.
patchPostMessage achieved my objective, no more red screen on ios when setting the onMessage property of a webview. JS code in an IOS webview could then talk to react-native