-
Notifications
You must be signed in to change notification settings - Fork 24.4k
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
react native html postMessage can not reach to WebView #11594
Comments
Without setTimeout() I'm getting:
However it does seem to work with the delay. |
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? |
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 function awaitPostMessage() {
let isReactNativePostMessageReady = !!window.originalPostMessage;
const queue = [];
let currentPostMessageFn = function store(message) {
if (queue.length > 100) queue.shift();
queue.push(message);
};
if (!isReactNativePostMessageReady) {
// const originalPostMessage = window.postMessage;
Object.defineProperty(window, 'postMessage', {
configurable: true,
enumerable: true,
get() {
return currentPostMessageFn;
},
set(fn) {
currentPostMessageFn = fn;
isReactNativePostMessageReady = true;
setTimeout(sendQueue, 0);
}
});
}
function sendQueue() {
while (queue.length > 0) window.postMessage(queue.shift());
}
} Usage: awaitPostMessage(); // Call this only once in your Web Code.
/* After you can call window.postMessage many times, and as soon as RN Message Bridge is ready - messadges delivered */
window.postMessage('Once :) ');
window.postMessage('Twice :) '); Notice: In my code i limit queue for 100 message, fell free to increase this, or remove limit at all. |
Thanks @Dryymoon, Do you know if it works in Android too ? |
@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. |
@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:
|
@beiming Thanks for this workaround. Setting the 0 millisecond timeout on 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. |
guys, this works on Android (i haven't tested it on iOS yet).
|
I think for Android you can use 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. |
@Dryymoon' s method is good, but in some env, you'd better use
|
@Dryymoon I'm curious why the |
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" |
@doxiaodong I think you need to replace the
Otherwise Webstorm is telling me that ECMAScript 5.1 doesn't support shorthand generator methods . |
For Android, the release version causes the error "__REACT_WEB_VIEW_BRIDGE.postMessage is not a function"!!! |
@shenlq if you disable proguard then it should work again In android/app/build.gradle def enableProguardInReleaseBuilds = false |
code works but now i am getting below error. any idea?
|
I had the same issue here. I managed to "solve it" as my code needs to be ran only when the user changes page, so I can bind it to |
For Android there's the For iOS I ended up using https://github.com/CRAlpha/react-native-wkwebview and it doesn't have this issue with the bridge. UIWebView also has a lot of issues that are fixed in WKWebView. Hope this helps. |
@pcstl could you please provide examples? |
I ran into What ended up working for me ended up being pretty simple:
|
"Setting onMessage on a WebView overrides existing values of window.postMessage, but a previous value was defined" - is normal usecase in DEV mode, but in PRODUCTION this check isnt running. Die to code https://github.com/facebook/react-native/blob/master/React/Views/RCTWebView.m#L283 |
Maybe solve problem, but check for native code in RN: https://github.com/facebook/react-native/blob/master/React/Views/RCTWebView.m#L285 String(window.postMessage) === 'function () { [native code] }' and String(Object.hasOwnProperty).replace('hasOwnProperty', 'postMessage') === 'function postMessage() { [native code] }' And it not equal But function awaitPostMessage() {
var isReactNativePostMessageReady = !!window.originalPostMessage;
var queue = [];
var currentPostMessageFn = function store(message) {
if (queue.length > 100) queue.shift();
queue.push(message);
};
if (!isReactNativePostMessageReady) {
var originalPostMessage = window.postMessage;
Object.defineProperty(window, 'postMessage', {
configurable: true,
enumerable: true,
get: function () {
return currentPostMessageFn;
},
set: function (fn) {
currentPostMessageFn = fn;
isReactNativePostMessageReady = true;
setTimeout(sendQueue, 0);
}
});
window.postMessage.toString = function () {
return String(originalPostMessage);
};
}
function sendQueue() {
while (queue.length > 0) window.postMessage(queue.shift());
}
} Usage: awaitPostMessage(); // Call this only once in your Web Code.
/* After you can call window.postMessage many times, and as soon as RN Message Bridge is ready - messages delivered */
window.postMessage('Once :) ');
window.postMessage('Twice :) '); Notice: In my code i limit queue for 100 message, fell free to increase this, or remove limit at all. |
The solution @andreibarabas tested on Android works great for me on iOS. How come we are going to so many extremes and not just using the I load my webview with this:
And usage of it:
|
Why was this closed? It hasn't been resolved and the current implementation is flawed requiring complex workarounds. |
Just a quick note, @Dryymoon this code fails in Safari 9 :/ It generates an
error, any thoughts on fixing? |
Also, just to reiterate. Placing comments inside the
|
I verify @jjzazuet comment - comments work on iOS but not on Android - thanks for that |
Can anyone please explain me why is it okay to do these "hacks" instead of just fixing RN's WebView so it won't override the global postMessage in a way that it's breaking the API? What am I missing here? Thanks! |
I used @Dryymoon solution and it has worked really well. Experiencing some issues in ios9 but I am working on supporting that now. I will post an update with an updated solution. |
guys, do you have any idea why a webview post message back and forth in a release build is super slow yet fast in a debug build? |
@Dryymoon |
I second @vvavepacket question. Why does webview post message seem much slower in production than in a debug build (at least in expo comparing development mode (~0.5s) vs production mode (>5s)? |
@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 |
apparently injected javascript code doesn’t work in android unless compressed (you can use this online tool http://javascriptcompressor.com/ ) |
@YusufHussein it doesn't have to be compressed. You just cannot use any comments. |
@Noitidart well I tried it without comments but it didn't work untill I compressed the code |
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. |
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...
|
Migrated issue to react-native-webview/react-native-webview#5. This one can be closed. |
Quick note about this fix for Android, if you used Use the |
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, whenpostMessage
is immediately run on head. I think it maybe related to HTML not finished loading. I then used a delay withsetTimeout
, and it worked.Now I want to know:
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
index.js
React Native web_view_page.js
Chrome console log
The text was updated successfully, but these errors were encountered: