Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

injectedJavaScript is not working in Webview of react native

I am not able to inject this simple js code into react-native webview.

I referred this link also but no solution provided here.

Then I found this one which works for html props but not uri.

import React, { Component } from 'react';
import { Platform,
  StyleSheet,
  Text,
  View,
  WebView
} from 'react-native';

export default class App extends Component<{}> {

  injectjs(){

    let jsCode = 'alert(hello)';
    return jsCode;
  }

  render() {
    return <WebView 
    javaScriptEnabled={true}
    injectedJavaScript={this.injectjs()} 
    source={{uri:"https://www.google.com"}} style={{ marginTop: 20 }} />;
  }
}
like image 283
Kapil Yadav Avatar asked Oct 11 '17 14:10

Kapil Yadav


3 Answers

You need to add onMessage props.

enter image description here

like image 92
wang sam Avatar answered Nov 09 '22 02:11

wang sam


I ran into this issue as well, and I was able to get it to work by setting mixedContentMode:

mixedContentMode={'compatibility'}

see below where props.url = {uri:'https://google.com'} quick test javascript pastes "look at me, I'm injecting" into the search box.

import React from 'react';
import { Button, StyleSheet, Text, View, ScrollView, WebView } from 'react-native';

export class WebViewController extends React.Component {

    constructor(props) {
        super(props);
    }

    render() {
        const url = this.props.url;
        console.log(`v:1`);
        console.log(`url info: ${JSON.stringify(url)}`);
        console.log(`javascript: ${Constants.javascript.injection}`);
        return (
            <View style={styles.root}>
                <WebView
                    source={url}
                    injectedJavaScript={Constants.javascript.injection}
                    mixedContentMode={'compatibility'}
                    javaScriptEnabled={true}
                    style={styles.webview}
                />
            </View>
        );
    }
}

const styles = StyleSheet.create({
    root: {
        flex:1,
        alignSelf: 'stretch',
    },
    webview: {
        flex:1,
        alignSelf: 'stretch',
    },
})

const Constants = {
    javascript: {
        injection: `
            Array.from(document.getElementsByTagName('input')).forEach((item) => {
                if(item.type == "search") {
                    item.value = "look at me, I'm injecting";
                }
            })
        `
    }
}

I expect the problem is when your adding your html directly and injecting javascript the webview considers the injection as javascript from the same origin. Unlike when you load a page through a url, where your javascript is foreign and is considered outside of the origin by the default value of mixedContentMode which is 'never'

see: https://facebook.github.io/react-native/docs/webview.html#mixedcontentmode

mixedContentMode Specifies the mixed content mode. i.e WebView will allow a secure origin to load content from any other origin.

Possible values for mixedContentMode are:

'never' (default) - WebView will not allow a secure origin to load content from an insecure origin. 'always' - WebView will allow a secure origin to load content from any other origin, even if that origin is insecure. 'compatibility' - WebView will attempt to be compatible with the approach of a modern web browser with regard to mixed content.

like image 21
Glorifundel Avatar answered Nov 09 '22 01:11

Glorifundel


Add onMessage method does work.

import React, { Component } from 'react';
import { Platform,
  StyleSheet,
  Text,
  View,
  WebView
} from 'react-native';

export default class App extends Component<{}> {
  render() {
    return 
      <WebView 
        javaScriptEnabled={true}
        injectedJavaScript={'alert("hello")'} 
        source={{uri:"https://www.google.com"}} style={{ marginTop: 20 }}
        onMessage={(event) => {
          console.log('event: ', event)
        }}
      />;
  }
}
like image 32
AmazingBeerBelly Avatar answered Nov 09 '22 02:11

AmazingBeerBelly