Skip to content

RCTWebView bridge redirection error fix#16502

Closed
samermurad wants to merge 2 commits intofacebook:masterfrom
samermurad:rctwebview-isMessagingEnabled-postMessageOverride
Closed

RCTWebView bridge redirection error fix#16502
samermurad wants to merge 2 commits intofacebook:masterfrom
samermurad:rctwebview-isMessagingEnabled-postMessageOverride

Conversation

@samermurad
Copy link

@samermurad samermurad commented Oct 23, 2017

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.

react-native-bug

Like stated above, this error occurs when the onMessage prop 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's delegate has

1) - (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 YES and only then will the WebView continue to execute the redirection load

2) - (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 webViewDidFinishLoad method
performs an extra check to validate if the window.postMessage was left untouched and raises the above mentioned error if it was.
The method then overrides the window.postMessage after saving it underwindow.originalPostMessage
i.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.originalPostMessage will be overriding again, deleting the original window.postMessage implementation

The applied fix adds two simple checks:

  1. Take window.originalPostMessage method into consideration and check whether it has the implementation of the window.postMessage method (dev env only)
  2. Check if the window.originalPostMessage exists before reassigning it with a new value

Test Plan

  1. populate the WebView onMessage prop in react native
  2. load the WebView from a custom html
  3. add an iframe to the html

behavior before fix: red error screen will be shown
expected behavior/after fix: everything will continue working normally as it should

Release Notes

… error "Setting onMessage on a WebView overrides existing values of window.postMessage,

but a previous value was defined."
@samermurad samermurad requested a review from shergin as a code owner October 23, 2017 14:56
@facebook-github-bot
Copy link
Contributor

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!

@pull-bot
Copy link

pull-bot commented Oct 23, 2017

Warnings
⚠️

📋 Test Plan - This PR appears to be missing a Test Plan.

@facebook-github-bot label Needs more information

@facebook-github-bot label Android

Attention: @shergin

Generated by 🚫 dangerJS

@facebook-github-bot facebook-github-bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Oct 23, 2017
@facebook-github-bot
Copy link
Contributor

Thank you for signing our Contributor License Agreement. We can now accept your code for this (and any) Facebook open source project. Thanks!

@facebook-github-bot
Copy link
Contributor

@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.

@samermurad
Copy link
Author

@shergin
This fix is a fix to the WebView component in iOS, this code (the WebView implementation) still exists in the latest version of react-native, what can I do to push this pull request further?
If this is stuck due to the android test error, then please take a look a the ci/circleci: test-android, it fails because some sort of a timeout.

@stale
Copy link

stale bot commented Feb 6, 2018

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.

@stale stale bot added the Stale There has been a lack of activity on this issue and it may be closed soon. label Feb 6, 2018
@stale stale bot closed this Feb 13, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. Stale There has been a lack of activity on this issue and it may be closed soon.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants