Repository navigation
Closed
Labels
Component: WebViewRelated to the WebView component.Related to the WebView component.Resolution: LockedThis issue was locked by the bot.This issue was locked by the bot.
Description
I use React Native webview to show index.html, and HTML will post messge to the app. The app will then receive the message and write it to console. The problem is the app cannot receive messages, when postMessage is immediately run on head. I think it maybe related to HTML not finished loading. I then used a delay with setTimeout, and it worked.
Now I want to know:
- Is there better way to solve this problem?
- Why the delay 100 milliscond did not work, but delay 200 milliscond did?
I am using React Native version 0.39.0, and Node version 7.2.0.
Here is the code I have so far:
index.html
<head>
<title>Index</title>
<script type="text/javascript" src="index.js"></script>
<script type="text/javascript">
// can not be received
postMessage('send to react native from index inline, no delay', '*');
// can not be received
setTimeout(function(){
postMessage('send to react native from index inline, delay 0 milliscond', '*')
}, 0);
// can received
setTimeout(function(){
postMessage('send to react native from index inline, delay 100 milliscond', '*')
}, 100);
onload = function() {
// can not be received
postMessage('send to react native from index inline after onload, no delay', '*')
// can received
setTimeout(function () {
postMessage('send to react native from index inline after onload, delay 0 milliscond', '*')
}, 0);
};
</script>
index.js
// can not be received
postMessage('send to react native from index.js, no delay', '*');
// can not be received
setTimeout(function() {
postMessage('send to react native from index.js, delay 100 milliscond', '*')
}, 100);
// can received
setTimeout(function() {
postMessage('send to react native from index.js, delay 200 milliscond', '*')
}, 200);
React Native web_view_page.js
return (
<WebView
source={{uri: 'http://127.0.0.1:8000/index.html'}}
onMessage={(event) => console.log('onMessage:', event.nativeEvent.data)}/>
);
Chrome console log
2016-12-21 11:45:02.367 web_view.js:147 onMessage: send to react native from index inline after onload, delay 0 milliscond
2016-12-21 11:45:02.491 web_view.js:147 onMessage: send to react native from index inline, delay 100 milliscond
2016-12-21 11:45:02.628 web_view.js:147 onMessage: send to react native from index.js, delay 200 milliscond
Reacted by Antero Fagerstedt, Faraz Sherwani, Mike Holloway, George Paul, Andrea Cresta, Karl Tarvas, fistuk, Clay Allsopp, Justin Mayfield, Peter and 20 more
Metadata
Metadata
Assignees
Labels
Component: WebViewRelated to the WebView component.Related to the WebView component.Resolution: LockedThis issue was locked by the bot.This issue was locked by the bot.
Activity
anttu commentedon Jan 8, 2017
Without setTimeout() I'm getting:
However it does seem to work with the delay.
farazs commentedon Jan 11, 2017
Having the same issue. If a message is sent right when the page is loaded and javascript is executed it fails with that error. However, if it's executed later it seems to work. Any update on this?
Dryymoon commentedon Jan 24, 2017
You can wait for RN postMessage bridge ready, by running this function once before any window.postMessage call in yours code, tested on RN 0.39
Usage:
Notice: In my code i limit queue for 100 message, fell free to increase this, or remove limit at all.
sylvainbaronnet commentedon Jan 27, 2017
Thanks @Dryymoon, Do you know if it works in Android too ?
ministerofpanic commentedon Jan 29, 2017
@Dryymoon Thanks for your solution. Do you know if this is intended behaviour? Seems a little odd to have to wait on the bridge to be ready to use before calling it.
I would expect the queueing behaviour to be taken care of automatically by react-native.
jqn commentedon Jan 31, 2017
@beiming In my case I wanted to trigger postMessage on click and I wasn't able to trigger the message until I added event.perventDefault() in my click event like this in the WebView page:
Also I'm able to trigger postMessage by wrapping it with:
gp3gp3gp3 commentedon Feb 8, 2017
@beiming Thanks for this workaround. Setting the 0 millisecond timeout on
window.onloadworks in iOS but doesn't seem to work on android unless I set it to 200.This still feels flimsy though, as I'm banking on I'm guessing the native bridge to be good to go at 200 milliseconds? I don't really know why this behavior is happening, but setting timeouts doesn't feel right.
andreibarabas commentedon Feb 21, 2017
guys, this works on Android (i haven't tested it on iOS yet).
farazs commentedon Mar 1, 2017
I think for Android you can use
window.__REACT_WEB_VIEW_BRIDGE.postMessageinstead.the delay for Android is in executing this:
You can use the javascript interface directly instead for Android based on the implementation. However, this could break in a future version if they update it.
doxiaodong commentedon Mar 15, 2017
@Dryymoon' s method is good, but in some env, you'd better use
es5code:farazs commentedon Apr 11, 2017
@Dryymoon I'm curious why the
setTimeoutis needed? Once the set is called we update thepostMessageand it should work right? It seems not to work without it but I'm not sure why.kyle-ilantzis commentedon Apr 12, 2017
For Android, Dryymoon's solution works when using the debug version. However, the release version causes the error "__REACT_WEB_VIEW_BRIDGE.postMessage is not a function"
chriscohoat commentedon Apr 21, 2017
@doxiaodong I think you need to replace the
get/setportion with the following:Otherwise Webstorm is telling me that ECMAScript 5.1 doesn't support shorthand generator methods .
shenlq commentedon Apr 27, 2017
For Android, the release version causes the error "__REACT_WEB_VIEW_BRIDGE.postMessage is not a function"!!!
kyle-ilantzis commentedon Apr 27, 2017
@shenlq if you disable proguard then it should work again
In android/app/build.gradle
def enableProguardInReleaseBuilds = false
27 remaining items
Karasynth commentedon Mar 22, 2018
@willhlaw @vvavepacket I am experience the same issue in production build. Any work around or update on this?
I am using react-native 0.54.2 and react-native-wkwebview-reborn 1.16.0
y-ghuzzi commentedon May 21, 2018
apparently injected javascript code doesn’t work in android unless compressed (you can use this online tool http://javascriptcompressor.com/ )
Noitidart commentedon May 21, 2018
@yusufhussein it doesn't have to be compressed. You just cannot use any comments.
y-ghuzzi commentedon May 22, 2018
@Noitidart well I tried it without comments but it didn't work untill I compressed the code
I am using react native 0.54.2 and Android simulator 6.0 Marshmallow
stale commentedon Aug 20, 2018
Hey there, it looks like there has been no activity on this issue recently. Has the issue been fixed, or does it still require the community's attention? This issue may be closed if no further activity occurs. You may also label this issue as "For Discussion" or "Good first issue" and I will leave it open. Thank you for your contributions.
kirillpisarev commentedon Aug 21, 2018
Still no luck posting a message on document ready within a WebView page without a dirty hack, suggested above. Is any hope that the problem will be solved without this mess, cuz it exists for about 2.5 years...
jamonholmgren commentedon Sep 9, 2018
Migrated issue to react-native-webview/react-native-webview#5. This one can be closed.
vladikoff commentedon Nov 6, 2018
Quick note about this fix for Android, if you used
postMessage.length === 1fix for your Android app, Chrome 70 (and maybe 69?) now reportspostMessage.lengthas1. So your app might be broken.Use the
[native code]fix or something likepostMessage.toString().includes('__REACT_WEB_VIEW_BRIDGE')