Skip to content

Add a injectJavaScript method to the WebView component - #11358

Closed
worm-emoji wants to merge 24 commits into
react:masterfrom
worm-emoji:master
Closed

worm-emoji wants to merge 24 commits into
react:masterfrom
worm-emoji:master

Conversation

@worm-emoji

@worm-emoji worm-emoji commented Dec 8, 2016 •

Copy link
Copy Markdown

Currently, < WebView > allows you to pass JS to execute within the view. This works great, but there currently is not a way to execute JS after the page is loaded. We needed this for our app.

We noticed that the WebView had messaging support added (see #9762) . Initially, this seemed like more than enough functionality for our use case - just write a function that's injected on initial load that accepts a message with JS, and eval() it. However, this broke once we realized that Content Security Policy can block the use of eval on pages. The native methods iOS provide to inject JS allow you to inject JS without CSP interfering. So, we just wrapped the native methods on iOS (and later Android) and it worked for our use case. The method injectJavaScript was born.

Now, after I wrote this code, I realized that #8798 exists and hadn't been merged because of a lack of tests. I commend what was done in #8798 as it sorely solves a problem (injecting JS after the initial load) and has more features than what I've done here (allows you to return the response). But, it uses eval() internally which makes it subject to Content Security Policy.

I'm not exactly sure what to do, but I think something should be merged. Perhaps I can add a way to try to return the results without using eval() but that seems tricky. I think the best way would be some sort of internal check when the WebView is loaded to see if CSP applies, and to not return a result on injected JavaScript (disable the use of eval() ) if that is the case. Or, you could make the argument that you don't need an evaluateJavascript function because you can accomplish it using the messaging features as it would work in all of the same places.

Looking for input - thanks.

Code was tested on iOS but not yet on Android - setting up my emulator later on.

@facebook-github-bot

Copy link
Copy Markdown
Contributor

By analyzing the blame information on this pull request, we identified @jacobp100 and @spicyj to be potential reviewers.

@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 Dec 8, 2016

@jacobp100 jacobp100 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good, clean implementation

@ericnakagawa

Copy link
Copy Markdown
Contributor

@lukemiles This looks like it could be a useful addition. I'm having someone from my team review.
@jacobp100 Thanks for reviewing, too.

@ericnakagawa

Copy link
Copy Markdown
Contributor

@lukemiles Can you add some tests to this PR?

@worm-emoji

Copy link
Copy Markdown
Author

@ericnakagawa On it!

@worm-emoji

Copy link
Copy Markdown
Author

@ericnakagawa Test added.

@yungsters yungsters left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code was tested on iOS but not yet on Android - setting up my emulator later on.

Have you had a chance to test this on Android, yet?

* because using eval() to return a response breaks
* this method on pages with a Content Security Policy
* that disallows eval(). If you need that functionality,
* look into postMessage/onMessage.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Can you fix the indentation here? (One too many spaces.)

* because using eval() to return a response breaks
* this method on pages with a Content Security Policy
* that disallows eval(). If you need that functionality,
* look into postMessage/onMessage.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto.

},
{
title: 'Inject JavaScript',
render(): React.Element<any> { return <InjectJS/>; }

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Space before />.

@mmmulani

Copy link
Copy Markdown
Contributor

iOS side lgtm

@worm-emoji

Copy link
Copy Markdown
Author

@yungsters:

screen shot 2016-12-12 at 5 19 05 pm

Managed to get it working on Android and fixed all the nits. Let me know what else this needs before it can be merged!

<View>
<WebView
ref={webview => { this.webview = webview; }}
style={{

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

quotes: Strings must use singlequote.

@SRandazzo

Copy link
Copy Markdown

Just what I came here looking for! Thanks @lukemiles for this, looking forward to it landing in master

@worm-emoji

Copy link
Copy Markdown
Author

Thanks @SRandazzo!

@jacobp100 @yungsters @ericnakagawa What more has to be done here to get this merged into master?

@jacobp100

Copy link
Copy Markdown
Contributor

Someone at Facebook has to merge it.

@worm-emoji

worm-emoji commented Jan 6, 2017 •

Copy link
Copy Markdown
Author

Made some stylistic changes thanks to suggestions @brentvatne made. Would love to know if there's anything else blocking this PR!

@brentvatne

Copy link
Copy Markdown
Collaborator

@facebook-github-bot shipit

@facebook-github-bot

Copy link
Copy Markdown
Contributor

@brentvatne has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator.

gitjake pushed a commit to gitjake/react-native that referenced this pull request Jan 20, 2017
Summary:
Currently, < WebView > allows you to pass JS to execute within the view. This works great, but there currently is not a way to execute JS after the page is loaded. We needed this for our app.

We noticed that the WebView had messaging support added (see react#9762) . Initially, this seemed like more than enough functionality for our use case - just write a function that's injected on initial load that accepts a message with JS, and `eval()` it. However, this broke once we realized that Content Security Policy can block the use of eval on pages. The native methods iOS provide to inject JS allow you to inject JS without CSP interfering. So, we just wrapped the native methods on iOS (and later Android) and it worked for our use case. The method injectJavaScript was born.

Now, after I wrote this code, I realized that react#8798 exists and hadn't been merged because of a lack of tests. I commend what was done in react#8798 as it sorely solves a problem (injecting JS after the initial load) and has more features than what I'
Closes react#11358

Differential Revision: D4390425

fbshipit-source-id: 02813127f8cf60fd84229cb26eeea7f8922d03b3
rozele pushed a commit to microsoft/react-native-windows that referenced this pull request Feb 8, 2017
Summary:
Currently, < WebView > allows you to pass JS to execute within the view. This works great, but there currently is not a way to execute JS after the page is loaded. We needed this for our app.

We noticed that the WebView had messaging support added (see #9762) . Initially, this seemed like more than enough functionality for our use case - just write a function that's injected on initial load that accepts a message with JS, and `eval()` it. However, this broke once we realized that Content Security Policy can block the use of eval on pages. The native methods iOS provide to inject JS allow you to inject JS without CSP interfering. So, we just wrapped the native methods on iOS (and later Android) and it worked for our use case. The method injectJavaScript was born.

Now, after I wrote this code, I realized that #8798 exists and hadn't been merged because of a lack of tests. I commend what was done in #8798 as it sorely solves a problem (injecting JS after the initial load) and has more features than what I'
Closes react/react-native#11358

Differential Revision: D4390425

fbshipit-source-id: 02813127f8cf60fd84229cb26eeea7f8922d03b3
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.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

9 participants