web-dev-qa-db-ja.com

reactJavaScriptのWebViewでJavaScriptが動作していません

この単純なjsコードを反応ネイティブのwebviewに挿入することはできません。

このリンクも参照しましたが、ここでは解決策を提供しませんでした。

そして、私はこれを見つけましたが、HTMLプロップでは動作しますが、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 }} />;
  }
}
7
Kapil Yadav

さて、ここには複数の問題があります。 1つ目は、Webビューをflexを含むビューコンポーネントでラップする必要があることです。1。次に、injectedJavascriptは文字列のみを受け入れ、関数は受け入れません。 3番目に、helloを定義せずに変数として使用しようとしているようです。または、文字列の場合、構文は次のようにする必要があります:jectedJavascript = {'alert( "hello")'}。さらに、ビューがロードされたときに、injectedJavascriptがすでに起動しているので、あなたがそれをやろうとしているのであれば、あなたはそこにいることができます。ただし、props、onLoadStart、およびinjectJavascriptの組み合わせを使用して、Webビューの読み込みが開始されたときにjavascriptを挿入できますが、実装はまったく異なるため、別の質問です。このコードを試してください:

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
colemerrick

私もこの問題に遭遇し、mixedContentModeを設定することで動作するようになりました。

mixedContentMode = {'compatibility'}

props.url = {uri: ' https://google.com '}を参照してください。クイックテストjavascriptが検索ボックスに「私を見て、注入しています」と貼り付けます。

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

問題は、htmlを直接追加してjavascriptをインジェクトすると、webviewが同じOriginからのjavascriptとしてインジェクションを考慮したときになると予想しています。 URLを介してページをロードする場合とは異なり、javascriptは外部のものであり、「never」であるmixedContentModeのデフォルト値によってOriginの外部と見なされます

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

mixedContentMode混合コンテンツモードを指定します。つまり、WebViewを使用すると、安全なOriginが他のOriginからコンテンツをロードできます。

MixedContentModeの可能な値は次のとおりです。

'never'(デフォルト)-WebViewは、安全なOriginが安全でないOriginからコンテンツをロードすることを許可しません。 'always'-WebViewは、そのOriginが安全でない場合でも、安全なOriginが他のOriginからコンテンツをロードできるようにします。 「互換性」-WebViewは、混合コンテンツに関して最新のWebブラウザのアプローチとの互換性を保とうとします。

3
Glorifundel

問題は、WebViewが完全にロードされた後にJavascriptコードを実行する必要があるためです。

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

setTimeoutが完全にロードされてから数秒後に、WebViewを使用してJavascriptコードをロードできます。

また、``の代わりに''を使用することをお勧めします。これを使用すると、変数内に他の変数を配置できます。

injectjs(){

    var message = "Hello";

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