3

我的应用程序正在使用jQuery.getScript()加载外部 javascript 文件。当我使用小书签或扩展程序启动应用程序时,一切正常。当应用程序通过 KBX 安装时,虽然在带有KBX 扩展名的Chrome中,javascript 文件中包含的函数不再可以在回调中访问,我得到:Uncaught ReferenceError: myfunc is not defined

有什么技巧可以访问包含的功能吗?

书签javascript:(function(){var d=document;var s=d.createElement('script');s.text="KOBJ_config={'rids':['a1135x30']};";d.body.appendChild(s);var l=d.createElement('script');l.src='http://init.kobj.net/js/shared/kobj-static.js';d.body.appendChild(l);})()

Chrome 扩展程序:crx

通过 KBX 安装的 url:KBX上的应用程序

这是规则集

ruleset a1135x30 {
  meta {
    name "test_external_js_loading"
    description <<
debugging external loading in kbx
    >>
    author "loic devaux"
    logging on
  }

  dispatch {
    domain ".*"

  }

  global {

  }

  rule first_rule {
    select when pageview ".*" setting ()
    // pre {   }
    // notify("Hello World", "This is a sample rule.");
    {
        emit <|

        $K.getScript('http\:\/\/lolo.asia/kynetx_debug/js/myfunc.js',function() {
                myfunc();
                /*
                * myfunc.js content:
                myfunc = function(){
                console.log('running myfunc');
                };
                */
            }
        );

        |>
    }  
  }
}
4

3 回答 3

3

我不完全确定您的问题与 KBX 运行代码的沙盒环境有关,但我认为可能。这是我写的一篇关于处理 KBX 沙盒环境的文章http://geek.michaelgrace.org/2011/03/kynetxs-new-sandboxed-browser-extensions/

来自博文

我最近发布了我的“Old School Retweet”Kynetx 应用程序在 Kynetx 应用商店中获取新发布的浏览器扩展。我非常喜欢新的扩展以及它们为用户和开发人员所做的一切。当我在应用商店发布应用时,我忘记了新扩展是沙盒的。由于扩展是沙盒的,因此扩展中的所有脚本的运行方式都与以前的 Kynetx 扩展中的脚本略有不同。无需过多讨论技术细节,之前的扩展只是将 JavaScript 注入页面,而新的扩展在沙箱中运行 JavaScript,该沙箱可以访问 DOM,但无法访问页面上的任何其他内容。由于这一变化,我的转推应用程序崩溃了,因为我使用 Twitter.com 加载的 jQuery 来显示新的推文框(我这样做是因为 Twitter. com 使用该库绑定单击事件并触发该事件,它必须来自绑定它的同一库)。谢天谢地,在朋友的帮助下,我能够解决 Firefox 和 Chrome 的沙盒环境。我是怎么做到的……如果应用程序不在沙箱中运行,我可以访问 Twitter.com 加载的 jQuery 以打开一个新的推文框

$("#new-tweet").trigger("click");

从 Firefox 沙箱内,我可以访问沙箱外的页面

window['$']("#new-tweet").trigger("click");

如果我在 Chrome 沙箱中,我可以创建一个包含我想要执行的 JavaScript 的脚本元素。粗鲁,但它有效。:)

var trigger_click_script = document.createElement("script");
var fallback = "window['$']('#new-tweet').trigger('click');";
trigger_click_script.innerHTML = fallback;
document.getElementsByTagName("head")[0].appendChild(trigger_click_script);

这是我最终得到的 JavaScript 代码,当用户单击转推按钮时会执行该代码。

// get stuff to retweet
var tweet = $K(this).parents(".tweet-content").find(".tweet-text").text();
var name = $K(this).parents(".tweet-content").find(".tweet-screen-name").text();

// build tweet
var retweet = "RT @"+name+" "+tweet;

// open new tweet box
$("#new-tweet").trigger("click");

// hack for FF sandbox
if ($("#tweet-dialog:visible").length === 0) {
  window['$']("#new-tweet").trigger("click");
}

// put tweet in new tweet box
$K(".draggable textarea.twitter-anywhere-tweet-box-editor").val(retweet).focus();
$K("#tweet_dialog a.tweet-button.button.disabled").removeClass("disabled");

// hack for chrome sandbox
if ($("#tweet-dialog:visible").length === 0) {
  var fallback = "window['$']('#new-tweet').trigger('click'); ";
  fallback += "window['$']('.draggable textarea.twitter-anywhere-tweet-box-editor').val('"+retweet+"').focus(); ";
  fallback += "window['$']('#tweet_dialog a.tweet-button.button.disabled').removeClass('disabled'); ";
  var trigger_click_script = document.createElement("script");
  trigger_click_script.innerHTML = fallback;
  document.getElementsByTagName("head")[0].appendChild(trigger_click_script);
}
于 2011-04-13T18:04:24.203 回答
1

你可以做的另一件事是让你的东西在沙盒之外访问是在窗口级别声明你的东西(违背了沙盒的目的,不推荐)。例如:如果你想在沙箱中执行一个console.log,console.log 不会记录到窗口控制台。但是,如果你说 window.console.log,它会的。因此,您可以(但不应该)通过以下方式声明 var:

window.myvar = "MyValue";

这将使 var 成为窗口级别的 var。尽管我反对这一点,但我已经做了一两次,以进行测试。

于 2011-04-14T05:10:34.023 回答
1

所以...我只是做了一些对 FF 和 Chrome 都有效的事情。它不漂亮,但这些都不是。很高兴为这两种方法提供一种解决方法,而不必对 FF 进行与 Chrome 不同的工作。我需要从全局对象中获取值......但沙箱阻止了它。有了这个 hack,我可以为两种浏览器做到这一点。

首先,从沙箱中......在 document.body 的底部添加一个不可见的 div

$K('body').append('<div id="randomdiv" style="display:none;"></div>');

然后在 document.head 中创建一个脚本,将 randomdiv 的文本设置为我需要的值。

var temp = '$("#randomdiv").text(twttr.currentUserScreenName);';    
var somescript = document.createElement("script");
somescript.innerHTML = temp;
document.getElementsByTagName("head")[0].appendChild(somescript);

然后......此时,在沙箱中,您可以从 DOM 中选择值,而不是从某个全局 js 对象中选择值。这就是你要做的。

var myvar = $K('#randomdiv').text();

让我知道你的想法。这对我来说是最容易的。

于 2011-05-23T06:02:07.910 回答