-
Notifications
You must be signed in to change notification settings - Fork 24.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[WebView] onMessage failing when there are JS warnings and errors on the page #10865
Comments
I should also add that I attempted to replicate the error on Android 7.0 and API 24 using a Nexus_5x emulator, and I got NO error. So this seems to be a platform specific error. |
I'm getting the same error. Seems like this exception is thrown when |
It’s because the page you’re visiting is overriding 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, injectedJavaScript="window.postMessage = String(Object.hasOwnProperty).replace('hasOwnProperty', 'postMessage');" 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. |
Well, when I try |
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. :( |
I have same error, without injecting any javascript to WebView - just setting WebView-properties: source={require('../lib/html/somefile.html')} 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: 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. |
+1, still has this problem |
There is an ongoing discussion in #10941 for the best way to go forward with this. It won't be in the next release or probably the release after. If you need this fixed now, fork the project and use the fix in the PR. |
+1, I'm getting the same error. When there is a |
+1,encounter this problem |
Again, there is a pr for this. We're aware this problem is affecting a lot of people. |
+1 getting the same error. |
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} /> |
@kyle-ilantzis tried this with RN 0.38.1, but still get the Red Screen. What version of RN are you on? |
@mschipperheyn I am using RN 0.39.0 The ios webview code between 0.39 and 0.38 is not different so it is odd you still get the red screen. https://github.com/facebook/react-native/blob/0.39-stable/React/Views/RCTWebView.m#L280 https://github.com/facebook/react-native/blob/0.38-stable/React/Views/RCTWebView.m#L280 |
Same issue with RN 0.40, as soon as we add 'onMessage' props to the WebView. |
Same issue with RN 0.42 with a WebView (without js injection) when I load PouchDB (6.1.2). |
@kyle-ilantzis I'm trying your solution with RN 0.42 but after using it I can't see pushCredentials = () => {
if (this.webview) {
this.webview.postMessage('Post message triggered');
}
}
onMessage = (e) => {
this.setState({ postMessage: e.nativeEvent.data });
};
// in render method
<WebView
ref={(ref) => { this.webview = ref; }}
source={{ uri}}
injectedJavaScript={patchPostMessageJsCode}
onMessage={this.onMessage}
/> |
@skrobek Do you mean pushCredentials() no longer causes onMessage() to be called?
|
@kyle-ilantzis Look at the docs example: class MessagingTest extends React.Component {
webview = null
state = {
messagesReceivedFromWebView: 0,
message: '',
}
onMessage = e => this.setState({
messagesReceivedFromWebView: this.state.messagesReceivedFromWebView + 1,
message: e.nativeEvent.data,
})
postMessage = () => {
if (this.webview) {
this.webview.postMessage('"Hello" from React Native!');
}
}
render(): ReactElement<any> {
const {messagesReceivedFromWebView, message} = this.state;
return (
<View style={[styles.container, { height: 200 }]}>
<View style={styles.container}>
<Text>Messages received from web view: {messagesReceivedFromWebView}</Text>
<Text>{message || '(No message)'}</Text>
<View style={styles.buttons}>
<Button text="Send Message to Web View" enabled onPress={this.postMessage} />
</View>
</View>
<View style={styles.container}>
<WebView
ref={webview => { this.webview = webview; }}
style={{
backgroundColor: BGWASH,
height: 100,
}}
source={require('./messagingtest.html')}
onMessage={this.onMessage}
/>
</View>
</View>
);
}
} |
@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 |
@kyle-ilantzis Yeah. Now I have huge problem because docs cause red screen and your solution helps with the red screen but block |
You could wait for the It worked for us, but we had to implement a simple queue in the webview that collects posts until the
|
@davidhellsing interesting to use the webview onLoad. With the injectedJavascipt solution I still needed to implement a queue in the webview |
The Workarounds are not working for me. |
If you feel brave, use a shell script to rename the native
After running this script (you will need to do it after each
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 |
@davidhellsing Nice patch :-) This appears to be working for me on iOS with RN 0.44 (haven't tried it on Android yet). |
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 (thow continiues to work in webkit) In chrome browser (Version 65.0.3325.181 (Official Build) (64-bit)) console type: ```js String(window.postMessage) === String(Object.hasOwnProperty).replace('hasOwnProperty', 'postMessage') ``` It still works in safari (Version 11.0.3 (13604.5.6)) A simplified version of how lodash are testing aginst it https://github.com/lodash/lodash/blob/4.0.1-npm-packages/lodash.isnative/index.js With a simpler description about this method can be found here: https://davidwalsh.name/detect-native-function Running: ```js RegExp('^' + String(Object.prototype.toString) .replace(/[.*+?^${}()|[\]\/\\]/g, '\\$&') .replace(/toString|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' ).test(String(window.postMessage)) ``` Works correctly in both chrome and safari. Affected issues: facebook#10865 - some hacks were seggested here to sidestep this issue. This PR should fix it outright
No matter what I do, if I try to implement onMessage it breaks the website. I am trying to render a meteor app in the Webview, and it depends on postMessage just working normally. This would be solved if we could just override the name of the postMessage, like lettings us specify a namespace window.reactNative.postMessage or just change it to window.RNPostmessage it doesn't even need to be a default, but giving the option to change it would fix all these problems. |
@jneuendorf |
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! |
@Titozzz Do I need to add the webview package to the |
@stonecold123 please open an issue on the new repo |
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 Hope this helps! |
@CharlesStover To goal of the community repo is to fix theses issues that were never fixed. The slimmening should allow everyone to move faster. We, of course, hope that expo will choose to add all the slimmening packages into their releases so that you don't have to depend on such workarounds |
You man are my hero! This is so simple and eloquent. It works for Expo 31 even when using iframes |
For me it helped to use 'useWebKit' prop on a 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.
The above code did nothing just patched window.postMessage function, the above issue will not appear. |
I can't get it to work properly, you can give an example that can work on https://snack.expo.io? I did something like that, but it seems that it doesn't work anymore. Code:
onMessage seems to receive nothing more, even if it worked before. |
The patched script makes my onMessage to be always called twice in iOS when i do a click event... |
If you still have this issue you can use code from above, to prevent this error like this: `const patchPostMessageFunction = function() { var patchedPostMessage = function(message, targetOrigin, transfer) { patchedPostMessage.toString = function() { window.postMessage = patchedPostMessage; Then you can append your own JS injection code like this:
This will prevent error from above but also this will prevent in some cases to use window.postMessage from your injected JS code. To go around this just wrap window.postMessage(msg) in timeout like this: |
Awesome man, if you come to Colombia I'll invite u some Empanadas. |
Is there an updated version of this answer which will work with the new version of react-native-webview ? I am unable to receive messages in onMessage() on both iOS and Android. :( |
Answering my own question here for everyone else's reference - (See - https://github.com/react-native-community/react-native-webview/releases/tag/v5.0.0)
Make sure you call windowPostMessageFix function first and then your second function -
I hope it helps ! Thanks ! |
This did solve the issue with the red screen, but when I tried to post data back from my frontend code calling |
I tested my app on Lollipop and it crashes due to a WebView issue listed here - As a result, our company is now moving away from React Native for Android. Sadly, there are too many breaking changes and too many security vulnerabilities in third party libraries. |
Description
I'm receiving this error (same as screenshot below):
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.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.
Other websites like google.com and github.com are just fine. If you want to replicate it, change the
uri
to yahoo.comAdditional Information
The text was updated successfully, but these errors were encountered: