通过 Chrome 上的 KBX 扩展程序安装时 Kynetx 应用程序无法运行
我的应用程序正在使用 jQuery.getScript() 加载外部 javascript 文件。当我使用书签或扩展程序启动应用程序时,一切正常。当应用程序通过 KBX 安装在 Chrome 内并带有 KBX 扩展时,javascript 文件中包含的函数将无法再在回调中访问,我得到:Uncaught ReferenceError: myfunc 未定义 。
有什么技巧可以访问包含的功能吗?
Bookmarklet : 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 安装的网址: KBX 上的应用程序 < /a>
这是规则集:
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');
};
*/
}
);
|>
}
}
}
My app is loading an external javascript file with jQuery.getScript(). When I use the bookmarklet or an extension to start the app everything works fine. When the app is installed through KBX though inside Chrome with the KBX extension the included functions inside the javascript file are not accessible in the callback anymore and I get : Uncaught ReferenceError: myfunc is not defined .
Is there any trick to get access to the included functions?
Bookmarklet : 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 extension : crx
url for installation via KBX : app on KBX
Here is the ruleset:
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');
};
*/
}
);
|>
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(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 以打开新的推文框
在 Firefox 沙箱内,我可以访问沙箱外的页面
如果我在 Chrome 沙箱中,我可以创建具有我想要执行的 JavaScript 的脚本元素。粗糙,但有效。 :)
这是我最终得到的 JavaScript 代码,当用户单击转发按钮时执行该代码。
]("#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");如果我在 Chrome 沙箱中,我可以创建具有我想要执行的 JavaScript 的脚本元素。粗糙,但有效。 :)
这是我最终得到的 JavaScript 代码,当用户单击转发按钮时执行该代码。
]('#new-tweet').trigger('click');"; trigger_click_script.innerHTML = fallback; document.getElementsByTagName("head")[0].appendChild(trigger_click_script);这是我最终得到的 JavaScript 代码,当用户单击转发按钮时执行该代码。
]("#new-tweet").trigger("click");如果我在 Chrome 沙箱中,我可以创建具有我想要执行的 JavaScript 的脚本元素。粗糙,但有效。 :)
这是我最终得到的 JavaScript 代码,当用户单击转发按钮时执行该代码。
]('#new-tweet').trigger('click'); "; fallback += "window[' ]("#new-tweet").trigger("click");如果我在 Chrome 沙箱中,我可以创建具有我想要执行的 JavaScript 的脚本元素。粗糙,但有效。 :)
这是我最终得到的 JavaScript 代码,当用户单击转发按钮时执行该代码。
]('#new-tweet').trigger('click');"; trigger_click_script.innerHTML = fallback; document.getElementsByTagName("head")[0].appendChild(trigger_click_script);这是我最终得到的 JavaScript 代码,当用户单击转发按钮时执行该代码。
]("#new-tweet").trigger("click");如果我在 Chrome 沙箱中,我可以创建具有我想要执行的 JavaScript 的脚本元素。粗糙,但有效。 :)
这是我最终得到的 JavaScript 代码,当用户单击转发按钮时执行该代码。
]('.draggable textarea.twitter-anywhere-tweet-box-editor').val('"+retweet+"').focus(); "; fallback += "window[' ]("#new-tweet").trigger("click");如果我在 Chrome 沙箱中,我可以创建具有我想要执行的 JavaScript 的脚本元素。粗糙,但有效。 :)
这是我最终得到的 JavaScript 代码,当用户单击转发按钮时执行该代码。
]('#new-tweet').trigger('click');"; trigger_click_script.innerHTML = fallback; document.getElementsByTagName("head")[0].appendChild(trigger_click_script);这是我最终得到的 JavaScript 代码,当用户单击转发按钮时执行该代码。
]("#new-tweet").trigger("click");如果我在 Chrome 沙箱中,我可以创建具有我想要执行的 JavaScript 的脚本元素。粗糙,但有效。 :)
这是我最终得到的 JavaScript 代码,当用户单击转发按钮时执行该代码。
]('#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); } ]("#new-tweet").trigger("click");如果我在 Chrome 沙箱中,我可以创建具有我想要执行的 JavaScript 的脚本元素。粗糙,但有效。 :)
这是我最终得到的 JavaScript 代码,当用户单击转发按钮时执行该代码。
]('#new-tweet').trigger('click');"; trigger_click_script.innerHTML = fallback; document.getElementsByTagName("head")[0].appendChild(trigger_click_script);这是我最终得到的 JavaScript 代码,当用户单击转发按钮时执行该代码。
]("#new-tweet").trigger("click");如果我在 Chrome 沙箱中,我可以创建具有我想要执行的 JavaScript 的脚本元素。粗糙,但有效。 :)
这是我最终得到的 JavaScript 代码,当用户单击转发按钮时执行该代码。
I'm not completely sure that your issue has to do with the sandboxed environment that the KBX runs your code in but I think it might. Here is a post I wrote about dealing with the sandboxed environment of the KBX http://geek.michaelgrace.org/2011/03/kynetxs-new-sandboxed-browser-extensions/
From blog post
I recently released my “Old School Retweet” Kynetx app in the Kynetx app store for the newly released browser extensions. I super love the new extensions and all that they do for users and developers alike. Something that I forgot when I released the app in the app store is that the new extension are sandboxed.
Because the extensions are sandboxed, all of the scripts from the extensions run a bit differently than they used to in the previous Kynetx extensions. Without getting into the technical details too much, the previous extensions just injected JavaScript into the page and the new extensions run JavaScript in a sandbox which has access to the DOM but can’t access anything else on the page. Because of this change my retweet app broke since I was using the jQuery loaded by Twitter.com to bring up the new tweet box (I do this because Twitter.com used that library to bind a click event and to trigger that event it has to be from the same library that bound it). Thankfully, with the help of a friend, I was able to get a work around for both Firefox and Chrome’s sandbox environment.
How I did it…
If the app is run not inside a sandbox I can just access the jQuery that Twitter.com loads to open a new tweet box
From within the Firefox sandbox I can access the page outside of the sandbox
If I am in the Chrome sandbox I can create a script element that has the JavaScript that I want to execute. Crude, but it works. : )
Here is the JavaScript code that I ended up with that gets executed when a user clicks on the retweet button.
]("#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");If I am in the Chrome sandbox I can create a script element that has the JavaScript that I want to execute. Crude, but it works. : )
Here is the JavaScript code that I ended up with that gets executed when a user clicks on the retweet button.
]('#new-tweet').trigger('click');"; trigger_click_script.innerHTML = fallback; document.getElementsByTagName("head")[0].appendChild(trigger_click_script);Here is the JavaScript code that I ended up with that gets executed when a user clicks on the retweet button.
]("#new-tweet").trigger("click");If I am in the Chrome sandbox I can create a script element that has the JavaScript that I want to execute. Crude, but it works. : )
Here is the JavaScript code that I ended up with that gets executed when a user clicks on the retweet button.
]('#new-tweet').trigger('click'); "; fallback += "window[' ]("#new-tweet").trigger("click");If I am in the Chrome sandbox I can create a script element that has the JavaScript that I want to execute. Crude, but it works. : )
Here is the JavaScript code that I ended up with that gets executed when a user clicks on the retweet button.
]('#new-tweet').trigger('click');"; trigger_click_script.innerHTML = fallback; document.getElementsByTagName("head")[0].appendChild(trigger_click_script);Here is the JavaScript code that I ended up with that gets executed when a user clicks on the retweet button.
]("#new-tweet").trigger("click");If I am in the Chrome sandbox I can create a script element that has the JavaScript that I want to execute. Crude, but it works. : )
Here is the JavaScript code that I ended up with that gets executed when a user clicks on the retweet button.
]('.draggable textarea.twitter-anywhere-tweet-box-editor').val('"+retweet+"').focus(); "; fallback += "window[' ]("#new-tweet").trigger("click");If I am in the Chrome sandbox I can create a script element that has the JavaScript that I want to execute. Crude, but it works. : )
Here is the JavaScript code that I ended up with that gets executed when a user clicks on the retweet button.
]('#new-tweet').trigger('click');"; trigger_click_script.innerHTML = fallback; document.getElementsByTagName("head")[0].appendChild(trigger_click_script);Here is the JavaScript code that I ended up with that gets executed when a user clicks on the retweet button.
]("#new-tweet").trigger("click");If I am in the Chrome sandbox I can create a script element that has the JavaScript that I want to execute. Crude, but it works. : )
Here is the JavaScript code that I ended up with that gets executed when a user clicks on the retweet button.
]('#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); } ]("#new-tweet").trigger("click");If I am in the Chrome sandbox I can create a script element that has the JavaScript that I want to execute. Crude, but it works. : )
Here is the JavaScript code that I ended up with that gets executed when a user clicks on the retweet button.
]('#new-tweet').trigger('click');"; trigger_click_script.innerHTML = fallback; document.getElementsByTagName("head")[0].appendChild(trigger_click_script);Here is the JavaScript code that I ended up with that gets executed when a user clicks on the retweet button.
]("#new-tweet").trigger("click");If I am in the Chrome sandbox I can create a script element that has the JavaScript that I want to execute. Crude, but it works. : )
Here is the JavaScript code that I ended up with that gets executed when a user clicks on the retweet button.
为了使您的内容可以在沙箱之外访问,您可以做的另一件事是在窗口级别声明您的内容(违背了沙箱的目的,并且不推荐)。例如:如果您想在沙箱内执行console.log,则console.log不会记录到窗口控制台。但是,如果你说 window.console.log,它就会。因此,您可以(但不应该)按以下方式声明 var:
这将使 var 成为窗口级 var。尽管我反对这样做,但为了测试,我已经这样做过一两次了。
Another thing that you can do to make your stuff accessible outside of the sandbox is the declare your stuff at the window level (defeats the purpose of the sandbox, and not recommended). For example: if you want to perform a console.log, whilst inside the sandbox, the console.log won't log to the window console. But, if you say window.console.log, it will. So, you could (but shouldn't) declare a var the following way:
That would make the var a window level var. Even though I am preaching against this, I have done it a time or two, for testing.
所以...我只是做了一些对 FF 和 Chrome 都有效的事情。这并不漂亮,但这些都不是真的。很高兴能够为两者提供一种解决方法,而不必为 FF 和 Chrome 采取不同的工作方式。我需要从全局对象中获取值......但沙箱阻止了这一点。通过这个技巧,我能够以一种方式为两种浏览器做到这一点。
首先,从沙箱中...将一个不可见的 div 添加到 document.body 的底部
,然后在 document.head 中创建一个脚本,将 randomdiv 的文本设置为我需要的值。
然后...此时,在沙箱中,您可以从 DOM 中选择值,而不是从某些全局 js 对象中选择值。这就是你要做的。
让我知道你的想法。这对我来说是最简单的。
So... I just did something that worked for both FF and Chrome. It isn't pretty, but none of this really is. It was nice to have one workaround for both instead of having to work differently for FF than Chrome. I needed to get the value from a global object... but the sandbox was blocking that. With this hack I was able to do that one way for both browsers.
First, from within the sandbox... add an invisible div to the bottom of the document.body
Then create a script in the document.head that will set the text of the randomdiv to the value that I needed.
Then... at this point, from within the sandbox, you can select the value from the DOM, rather than from some global js object. This is how you would do it.
Let me know your thoughts. This is what was the easiest for me.