RCTWebView bridge redirection error fix#16502
RCTWebView bridge redirection error fix#16502samermurad wants to merge 2 commits intofacebook:masterfrom
Conversation
… error "Setting onMessage on a WebView overrides existing values of window.postMessage, but a previous value was defined."
|
Thank you for your pull request and welcome to our community. We require contributors to sign our Contributor License Agreement, and we don't seem to have you on file. In order for us to review and merge your code, please sign up at https://code.facebook.com/cla. If you are contributing on behalf of someone else (eg your employer), the individual CLA may not be sufficient and your employer may need the corporate CLA signed. If you have received this in error or have any questions, please contact us at cla@fb.com. Thanks! |
@facebook-github-bot label Needs more information @facebook-github-bot label Android Attention: @shergin Generated by 🚫 dangerJS |
|
Thank you for signing our Contributor License Agreement. We can now accept your code for this (and any) Facebook open source project. Thanks! |
|
@samermurad I tried to find reviewers for this pull request and wanted to ping them to take another look. However, based on the blame information for the files in this pull request I couldn't find any reviewers. This sometimes happens when the files in the pull request are new or don't exist on master anymore. Is this pull request still relevant? If yes could you please rebase? In case you know who has context on this code feel free to mention them in a comment (one person is fine). Thanks for reading and hope you will continue contributing to the project. |
|
@shergin |
|
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Maybe the issue has been fixed in a recent release, or perhaps it is not affecting a lot of people. If you think this issue should definitely remain open, please let us know why. Thank you for your contributions. |
Fixing RCTWebView redirection error
Motivation
Inspired by following tickets: 10941, 10865
On iOS, when working with RCTWebView and bridging between react native and native JavaScript (i.e: _isMessagingEnabled == YES)
any redirection done on the JavaScript side raises the following error on the dev env:
Setting onMessage on a WebView overrides existing values of window.postMessage, but a previous value was defined.Like stated above, this error occurs when the
onMessageprop in the react native side is set and used.In order to understand this error and why it happens, one must understand two methods
That The native iOS
UIWebView'sdelegate has1) - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
This method is called each time a redirection occurs on the browsers' JS side, and not just for the main window (i.e: for iframes as well; keep that part in mind).
If the method returns
YESand only then will the WebView continue to execute the redirection load2) - (void)webViewDidFinishLoad:(UIWebView *)webView
Each successful load (be it a redirection or a page load) will call this method, pretty simple.
The Problem
When having a bridge between RN and native JS, the
webViewDidFinishLoadmethodperforms an extra check to validate if the
window.postMessagewas left untouched and raises the above mentioned error if it was.The method then overrides the
window.postMessageafter saving it underwindow.originalPostMessagei.e:
window.originalPostMessage = window.postMessage; window.postMessage = function(data) { /* New code */}While this solution is sufficient for cases where there is a simple one page bridge, it doesn't cover cases where these delegate methods will be called again due to any kind of redirection that doesn't kill the last modified window (i.e: iframes).
This solution only takes care of cases where the main window changes (navigating to a new page).
If these delegate methods will be called again, the first dev check will fail, showing the error; and the
window.originalPostMessagewill be overriding again, deleting the originalwindow.postMessageimplementationThe applied fix adds two simple checks:
window.originalPostMessagemethod into consideration and check whether it has the implementation of thewindow.postMessagemethod (dev env only)window.originalPostMessageexists before reassigning it with a new valueTest Plan
behavior before fix: red error screen will be shown
expected behavior/after fix: everything will continue working normally as it should
Release Notes