【问题标题】:Issue injecting external script with executeScript method in Cordova在 Cordova 中使用 executeScript 方法注入外部脚本的问题
【发布时间】:2014-04-03 10:45:21
【问题描述】:

我正在编写一个虚拟应用程序来测试 Cordova 的 InAppBrowser 插件中的 executeScript() 方法是如何工作的。特别是,我试图在一个 webview 中注入一个 javascript 代码。

这是我的 index.html 文件:

<!DOCTYPE html>
<html>
    <head>

        <meta charset="utf-8" />
        <meta name="format-detection" content="telephone=no" />
        <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height, target-densitydpi=device-dpi" />
        <link rel="stylesheet" type="text/css" href="css/style.css" />
        <script type="text/javascript" src="phonegap.js"></script>
        <script type="text/javascript" src="js/index.js"></script>
        <title>InAppBrowser Injection Test</title>
    </head>
    <body>
        <div class="app">
            <h1>Testing Injection</h1>
            <div id="deviceready" class="blink">
                <p class="event listening">Starting Mother WebView</p>
                <div class="event received">
                  <p>Device is Ready</p>
                </div>
            </div>
        </div>
        <script type="text/javascript">
            app.initialize();
        </script>
    </body>
</html>

还有 index.js 文件

var app = {

    initialize: function() {
        this.bindEvents();
    },

    bindEvents: function() {
        document.addEventListener('deviceready', this.onDeviceReady, false);
    },

    onDeviceReady: function() {
        app.receivedEvent('deviceready');
        var ref = window.open('http://www.example.net', '_blank', 'location=yes ,toolbar=yes, EnableViewPortScale=yes');
        ref.addEventListener('loadstart', function(event) { alert('start: ' + event.url); });
        ref.addEventListener('loadstop', function() {

        //ref.executeScript({ code: "alert('Injected Code')" });

        ref.executeScript({ file: "externaljavascriptfile.js" });
        showalert();

        });
       ref.addEventListener('loaderror', function(event) { alert('error: ' + event.message); });
       ref.addEventListener('exit', function(event) { alert(event.type); });      
    },


    receivedEvent: function(id) {
        var parentElement = document.getElementById(id);
        var listeningElement = parentElement.querySelector('.listening');
        var receivedElement = parentElement.querySelector('.received');
        listeningElement.setAttribute('style', 'display:none;');
        receivedElement.setAttribute('style', 'display:block;');
        console.log('Received Event: ' + id);
   }
};

最后是 externaljavascriptfile.js

 alert('External Injected Code');

如果我尝试直接注入 javascript 代码(即取消注释 "ref.executeScript({ code: "alert('Injected Code')" });" 行)一切正常,并且在页面加载后触发警报,但是如果我尝试注入外部 javascript(即使用“ref.executeScript({ file: "externaljavascriptfile.js" });”行,则不会发生任何事情。

我错过了什么吗?

【问题讨论】:

  • 谢谢你的回答,但你也错过了重点。您链接的讨论是关于通过本机应用程序注入 javascript,这基本上是一个 Java 程序。我需要做同样的事情,但要通过 Phonegap/cordova。

标签: javascript cordova inappbrowser


【解决方案1】:

其实我想你已经知道答案了。

executeScript() 方法在子 WebView 中运行。

ref.executeScript({ file: "externaljavascriptfile.js" });

在您的代码中,executeScript() 方法被引用 http://www.example.net/externaljavascriptfile.js,而不是在您的脚本文件中 /www/jscordova 目录中。因为executeScript() 方法在 childview 中注入了 JavaScript,如你所知。

您可以使用以下代码测试代码。我已将文件放在我的网站上。

//...
onDeviceReady: function() {
  var ref = window.open('http://www.haruair.com/', '_blank', 'location=yes, toolbar=yes, EnableViewPortScale=yes');
  ref.addEventListener('loadstop', function() {
    ref.executeScript({ file: "externaljavascriptfile.js" });
  });
},
//...

仅供参考,如果需要从 childview 获取数据,可以使用回调。

//...
var ref = window.open('http://www.haruair.com/', '_blank', 'location=yes, toolbar=yes, EnableViewPortScale=yes');
ref.addEventListener( "loadstop", function() {
  ref.executeScript(
    { file:'http://haruair.com/externaljavascriptfile.js' },
    function() {
      ref.executeScript(
        { code:'getSomething()' },
        function(values){
          var data = values[0];
          alert(data.name);
        });
    }
  );
});
//...

externaljavascriptfile.js:

var getSomething = function(){
  // do something and get the result from childview webpage
  return { name : 'foo', age : 12 };
};

【讨论】:

  • 好答案,“externaljavascriptfile.js”是指无法访问应用程序资产(位于不同的“服务器”上)的子视图的根目录。因此,最好的猜测是将 js 内容加载到变量中,并通过“code:”声明发送。
  • 为了完成: ... getAsset: function(theUrl) { var xmlHttp = new XMLHttpRequest(); xmlHttp.open("GET", theUrl, false); xmlHttp.send(空);返回 xmlHttp.responseText; } ...会成功的!
  • 爱德华好。天才解决方案!
  • 使用_self选项时,此解决方案不起作用。
  • 这个连接有多好?是否可以创建一个返回window 对象的getWindow() 函数,以便我们可以addEventListener,例如?
【解决方案2】:

使用Ajax获取JS文件数据,然后使用执行脚本注入

$.ajax({
    type: "GET",
    url: cordova.file.applicationDirectory + "www/js/externalScript.js",
    dataType: "text",   
    success: function (jsCode) {
        ref.executeScript({code: jsCode}, function () {
            console.log("Code Inserted Succesfully");
        });
    },
    error: function () {
       console.log("Ajax Error");
    }
});

//ref is reference of inappbrowser
//i.e. var ref = window.open();
//url is url of your local javascript file

通过此方法,您可以添加一个脚本文件,该脚本文件位于本地APP的沙箱中,而不是在互联网上。

注意,你需要cordova-plugin-file: 科尔多瓦插件添加科尔多瓦插件文件

【讨论】:

  • 这应该是公认的答案,因为你可以添加一个脚本文件,它在本地APP沙箱中,而不是在互联网上
  • 在 2020 年尝试这一点,但我没有成功。这仍然对你有用吗?
【解决方案3】:

您是否安装了 inappbrowser 插件?

我在 android 中的工作如下:

编辑:针对科尔多瓦 7 更新

创建 phonegap 项目

> cordova create JsExec

> cd JsExec

> cordova platform add android

> cordova plugin add cordova-plugin-inappbrowser

更新 index.js - 这是我的 onDeviceReady 函数:

onDeviceReady: function() {
    this.receivedEvent('deviceready');

    var w = window.open('http://www.example.net','_blank','location=yes');
    w.addEventListener('loadstop', function(event) {
      w.executeScript({file: "https://s3.amazonaws.com/avvi00/externaljavascriptfile.js"});
    });
},

部署到我的 HTC

> cordova run --device

外部脚本文件为here

这个项目的完整工作副本是here

问候,

平均

【讨论】:

  • @whitedeath - 为 cordova 7 更新了新链接。谢谢你告诉我。
  • 如何加载存储在 www 文件夹中的本地文件?
【解决方案4】:

externaljavscriptfile.js 未链接到您的 html 文件中。 您需要将其包含在

<script type="text/javascript" src="path/externaljavascriptfile.js"></script>

标记或动态加载它:

var script = document.createElement('script');
script.async = "async";
script.src = "path/externaljavascriptfile.js";
document.getElementsByTagName("head")[0].appendChild( script );

注意:您可能需要将代码放入函数中才能执行。

希望它有效。

【讨论】:

  • 感谢您的回答,但您没有抓住重点。我需要的是能够在我浏览器通过应用程序的每个页面中注入一些 javascript。开发原生应用程序非常容易(创建一个 webview 浏览器并注入 .js 文件)。我想对phonegap做同样的事情。该 html 文件仅用于创建一个“母亲 Webview”,它将通过 index.js 生成一个“子 WebView”。孩子应该正在浏览网页,母亲应该在每次页面加载时将 .js 文件注入孩子。目前我可以注入 javascript 代码 (alert('Injected Code')),但不能注入 .js 文件。
  • 抱歉耽搁了。我不知道...尝试使用 .js 文件的完整路径而不是缩短的路径...
猜你喜欢
  • 1970-01-01
  • 2011-10-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多