Home » Android » javascript – injectedJavaScript is not working in Webview of react native

javascript – injectedJavaScript is not working in Webview of react native

Posted by: admin June 15, 2020 Leave a comment

Questions:

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 }} />;
  }
}
How to&Answers:

Well, you have more than one issue here. First one is your web view needs to be wrapped in a containing View component with flex: 1. Second, injectedJavascript only accepts a string – not a function. Third, it seems you are attempting to use hello as a variable without defining it, or if it is a string than your syntax needs to be something like this: injectedJavascript={‘alert(“hello”)’}. Furthermore, injectedJavascript is already fired when the view loads so you are all good there if that’s what you are intending to do. You can inject javascript when the web view starts loading though, using a combination of the props, onLoadStart and injectJavascript, but the implementation is quite different, so that’s a different question. Try this code:

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

export default class App extends Component {

  render() {
    let yourAlert = 'alert("hello")'
    return (
     <View style={{flex: 1}}>
       <WebView
        javaScriptEnabled={true}
        domStorageEnabled={true}
        injectedJavaScript={yourAlert}
        source={{ uri: "https://www.google.com" }} style={{ marginTop: 20  }} />
    </View>
   )
  }
}

Answer:

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.

Answer:

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)
        }}
      />;
  }
}