web-dev-qa-db-fra.com

injectedJavaScript ne fonctionne pas dans la vue Web de react native

Je ne suis pas capable d'injecter ce code js simple dans la visualisation Web réactive.

J'ai référé ce lien aussi mais aucune solution fournie ici.

Ensuite, j'ai trouvé celui qui fonctionne pour les accessoires HTML, mais pas 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 }} />;
  }
}
4
Kapil Yadav

Eh bien, vous avez plus d'un problème ici. La première est que votre vue Web doit être encapsulée dans un composant Vue contenant avec flex: 1. Deuxièmement, injectedJavascript accepte uniquement une chaîne - pas une fonction. Troisièmement, il semble que vous tentiez d'utiliser hello en tant que variable sans la définir, ou bien s'il s'agit d'une chaîne, votre syntaxe doit ressembler à ceci: injectedJavascript = {'alert ("hello")'}. De plus, injectedJavascript est déjà déclenché lors du chargement de la vue, donc vous y êtes si bon si c'est ce que vous avez l'intention de faire. Vous pouvez injecter du code javascript lorsque le chargement de la vue Web commence à se faire, en utilisant une combinaison des accessoires, onLoadStart et injectJavascript, mais la mise en œuvre est très différente, ce qui en fait une question différente. Essayez ce 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>
   )
  }
}
5
bagofcole

J'ai rencontré ce problème également et j'ai pu le faire fonctionner en définissant mixedContentMode:

mixedContentMode = {'compatibilité'}

voir ci-dessous où props.url = {uri: ' https://google.com '} test rapide, le test rapide colle en javascript "regardez-moi, je m'injecte" dans le champ de recherche.

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";
                }
            })
        `
    }
}

Je suppose que le problème vient du moment où vous ajoutez directement votre code HTML et que vous injectez du javascript dans la visualisation Web, l'injection est considérée comme du javascript de la même origine. Contrairement à lorsque vous chargez une page via une URL, où votre javascript est étranger et est considéré en dehors de l'origine par la valeur par défaut de mixedContentMode qui est "jamais".

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

mixedContentMode Spécifie le mode de contenu mixte. i.e WebView permettra à une origine sécurisée de charger du contenu provenant d’une autre origine.

Les valeurs possibles pour mixedContentMode sont:

'never' (par défaut) - WebView n'autorisera pas une origine sécurisée à charger du contenu provenant d'une origine non sécurisée . 'toujours' - WebView autorisera une origine sécurisée à charger du contenu à partir de toute autre origine, même si cette origine n'est pas sécurisée. 'compatibilité' - WebView tentera d’être compatible avec l’approche d’un navigateur Web moderne en ce qui concerne le contenu mixte.

1
Glorifundel

Le problème vient du fait que le code Javascript doit être exécuté après le chargement complet de WebView.

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

export default class App extends Component {

  injectjs() {

    let message = "Hello";

    let jsCode = `
      setTimeout(() => {
        alert('${message}');
      }, 1500)`;

    return jsCode;
  }

  render() {
    return <WebView
      javaScriptEnabled={true}
      injectedJavaScript={this.injectjs()}
      source={{ uri: "https://www.google.com" }} style={{ marginTop: 20 }} />;
  }
}

Vous pouvez utiliser setTimeout pour charger votre code Javascript quelques secondes après le chargement complet de WebView.

De plus, je vous recommande d'utiliser `` au lieu de '', vous pouvez insérer d'autres variables dans votre variable.

Exemple 

injectjs(){

    var message = "Hello";

    let jsCode = `alert('${message}')`;
    return jsCode;
}
0
Mateo Guzmán