facebook / react-native

A framework for building native applications using React
https://reactnative.dev
MIT License
119.26k stars 24.35k forks source link

[WebView] Message passing between WebView / Javascript #586

Closed notduncansmith closed 9 years ago

notduncansmith commented 9 years ago

It would be really great to be able to run JS inside of a WebView component and register event listeners within regular React Native code.

My specific use-case is PouchDB, which really wants to run either in Node.js or the browser; however, there are lots of libraries that are designed to work within one or the other of the existing JS runtimes, but would still be useful to a React Native app.

I'm thinking something along these lines, perhaps register a react:// protocol or something for message passing - though I'd love to hear about a cleaner way to implement it.

ghost commented 9 years ago

+1. That would be quite handy indeed.

nwjohn commented 9 years ago

+1, also fits my use case.

hedgerwang commented 9 years ago

I came up this hacky approach to send message from the webview's HTML back to the react native. The idea is to generate a navigation change event from web page so that the react native can catch it.

var WebViewExample = React.createClass({

  getInitialState() {
    return {
      message: '....',
    };
  },

  render() {
    var html = `
      <html>
        <script>
          var pinID = 0;
          function ping() {
            var message = 'hello ' + Date.now();
            document.title = message;
            window.location.hash = pinID++;
            return false;
          }
        </script>
        <body>
          This is a HTML Page inside WebView
          <hr />
          <button onClick="window.location.hash = ping()">ping</button>
        </body>
      </html>
    `;

    return (
      <View>
        <Text style={{display: 'block'}}>Native View</Text>
        <Text style={{display: 'block'}}>{this.state.message}</Text>
        <Text style={{display: 'block'}}>Web View</Text>
        <WebView
          automaticallyAdjustContentInsets={false}
          style={{height: 400}}
          html={html}
          onNavigationStateChange={this.onNavigationStateChange}
          startInLoadingState={false}
        />
      </View>
    );
  },

  onNavigationStateChange(navState) {
    this.setState({
      message: navState.title,
    });
  },
});
sahrens commented 9 years ago

We can also just run all of the ReactNative JS in a WKWebView - would that make PouchDB happy? We could potentially make the executor mode configurable per app so you could use that instead of JSC if you prefer that tradeoff (more latency, probably more memory, etc).

sophiebits commented 9 years ago

@sahrens Even if we do that, I'm not sure if we'd want to allow access to all DOM APIs?

I'm don't think that running incompatible libraries in a headless web view is likely the right solution, but there certainly are cases where you'd want to have something in a web view and pass messages to it, so maybe we could add something here.

brentvatne commented 9 years ago

@notduncansmith - any interest in this still? if so, a PR would be welcome! you can ping me on irc/twitter @notbrent (nice username, by the way) if you need a hand

Intellicode commented 9 years ago

I had a go at this, and I got basic messages working using the techniques described at the Stackoverflow page. However, I was wondering how Apple would look at this feature since it allows remote websites execute code (sort of). Titanium seems to allow communication if the code is loaded from a local source (http://docs.appcelerator.com/titanium/3.0/#!/guide/Communication_Between_WebViews_and_Titanium). Any thoughts on this?

brentvatne commented 9 years ago

@Intellicode - it seems like Titanium allows some actions to be triggered on remote sites as well - that said, I think the best angle here is to pull this out into an external library where we can discuss it and iterate on it and when it is mature enough potentially integrating it back into React Native. Are you willing to do that? It would be awesome :smile:

Intellicode commented 9 years ago

I'll have a go at it this weekend, should be a good learning opportunity :)

kevlened commented 9 years ago

I was able to get this to work: https://github.com/alinz/react-native-webview-bridge

The example included in the repo was more helpful than the docs.

UPDATE: Be aware of this issue - https://github.com/alinz/react-native-webview-bridge/issues/3

Intellicode commented 9 years ago

nice, I guess I can stop working on my version then :)

christopherdro commented 9 years ago

@ide @brentvatne Issue can be closed. Anyone looking for this functionality can take a look at https://github.com/alinz/react-native-webview-bridge.

gre commented 9 years ago

I really wish this was built-in in WebView, communication between WebView and the React Native component feel to me to be a core feature you expect from WebView.

sophiebits commented 9 years ago

@gre I imagine we'd take a high-quality PR for this. You can see my comments on #1191.

gs-akhan commented 9 years ago

@spicyj What could add some relief is having some query params on the URL being added to the WebView. This way we could at least send data one way (Is there any way to get this now ?) . Sending Data back and forth is for sure a core requirement, I am thinking why would React-Native not do this natively.

        <WebView 
              scrollEnabled = {false}
              style = {styles.webView}
              url = "index.html?data=<base64EncodedStuff>"
            />

Thanks

sophiebits commented 9 years ago

I don't know. I don't work actively on React Native. Generally, if things haven't been implemented it means that there hasn't been much demand at Facebook for a feature and often means that there hasn't been much demand externally either. This is a community project and if you want to improve the components, please send pull requests.

gs-akhan commented 9 years ago

@spicyj Thanks :)

pglotov commented 8 years ago

Is there any way to implement a callback of WebView in JS? E.g. in Android WebViewClient has a method shouldOverrideUrlLoading() which I'd like to override in RN. Is it possible?

gre commented 8 years ago

@pglotov I recommand to use https://github.com/alinz/react-native-webview-bridge . for the moment it's only for iOS but see in issues, someone has worked on an android version.

pglotov commented 8 years ago

@gre thanks, interesting stuff. But seems like an overkill for my purpose. I'll try to make the shouldOverrideUrlLoding() work. It is similar in purpose to already existing onShouldStartLoadWithRequest() iOS callback, so it makes sense to have one for Android as well.

mchev2 commented 8 years ago

+1 for shouldOverrideUrlLoding on Android

kevinejohn commented 8 years ago

+1 for shouldOverrideUrlLoading on Android

chenxiaohu commented 8 years ago

+1 for shouldOverrideUrlLoading on Android

lu-ko commented 8 years ago

+1 for shouldOverrideUrlLoading on Android

jordaaash commented 8 years ago

+1 for shouldOverrideUrlLoading on Android. Without this API exposed, all sorts of links break the WebView (mailto:, target="_blank", links to external sites, etc).

pglotov commented 8 years ago

Implemented shouldOverrideUrlLoading in this PR.

saulshanabrook commented 8 years ago

I want to use the Web Cryptography API (window.crypto) in React Native, and I am thinking about doing that by calling window.crypto in a WebView and using https://github.com/alinz/react-native-webview-bridge to pass the information back. This seems rather laborious, however, and potentially rather slow.

I have limited experience with React Native, so I am unsure if there is a faster/simpler way of achieving this.

dangnelson commented 8 years ago

This issue should be reopened as https://github.com/alinz/react-native-webview-bridge no longer works with the latest version of react-native, and the author is no longer supporting it as he's pushing to get it implemented into RN core.

tulasi-ram commented 8 years ago

Hi, I want to navigate from react native webview to Android Activity when tap on React Native webview. I tried to use native-webview-bridge. Seems it was a wrapper class of Webview. It doing communication or bypass daata between webview to react native.

tslater commented 8 years ago

I would really like to see this issue opened. It should be a core feature.

svbatalov commented 8 years ago

Already in v0.37.0. See this issue.

lesnitsky commented 7 years ago

Hi, Just want to share my wrapper react-native-webview-messaging with more convenient API than in core RN WebView. Check it out and don't hesitate to submit an issue if smth is not working on your end, I'd be just glad to make it useful not only for our team 😏