2014-02-12 198 views
8

我想开发只能在指定页面上工作的扩展 - 如果页面所有者在其代码中添加全局变量(例如ACCEPT_STATS = true;)我想执行指定的代码。Chrome扩展 - 从扩展访问文档/页面变量

我已经绑定我的函数onload事件,我还发现,解决方案是如何做到这一点在Firefox:

var win = window.top.getBrowser().selectedBrowser.contentWindow; 
if (typeof win.wrappedJSObject.ACCEPT_STATS !== 'undefined') { 
    // code to run if global variable present 
} 

,但我不能让Chrome在这项工作。有没有可能访问文档的全局变量抛出Chrome扩展代码?

我的扩展的代码被注入为内容脚本。

+0

这听起来象是一个内容脚本应该做的,不是吗? https://developer.chrome.com/extensions/content_scripts.html –

+0

“但是,内容脚本有一些限制,它们不能:[...] 使用由网页或其他内容脚本定义的变量或函数” – kmoe

+0

内容脚本在_isolated world_中执行。你将不得不将代码注入页面。 –

回答

1

运行在页面上的JavaScript运行在与您使用内容脚本注入的JavaScript不同的“孤立的世界”中。由于安全原因,Chrome浏览器会将这两个世界分开,因此您无法在任何窗口中阅读window.XYZ。更多关于独立世界如何工作的信息:http://www.youtube.com/watch?v=laLudeUmXHM

实现此功能的正确方法是通过window.postMessage API与页面进行通信。我这里还有我怎么会去一下:

  1. 注入内容脚本到各选项卡
  2. 通过window.postMessage
  3. 将消息发送给标签
  4. 如果页面了解到此消息,它正确响应(再次通过window.postMessage)
  5. 内容脚本执行它需要执行的代码。

HTH

13

是,包括脚本到页面并运行从网页运行脚本一个孤立的环境。

但是,可以通过将内联脚本通过附加到文档的html脚本标签推入运行时上下文来解决孤立的世界问题。该内联脚本然后可以抛出一个自定义事件。

孤立的上下文中包含的脚本可以监听该事件并相应地作出响应。

因此,在你包含脚本代码会是这个样子:

// inject code into "the other side" to talk back to this side; 
var scr = document.createElement('script'); 
//appending text to a function to convert it's src to string only works in Chrome 
scr.textContent = '(' + function() { 
    var check = [do your custom code here]; 
    var event = document.createEvent("CustomEvent"); 
    event.initCustomEvent("MyCustomEvent", true, true, {"passback":check}); 
    window.dispatchEvent(event); } + ')();' 
//cram that sucker in 
(document.head || document.documentElement).appendChild(scr); 
//and then hide the evidence as much as possible. 
scr.parentNode.removeChild(scr); 
//now listen for the message 
window.addEventListener("MyCustomEvent", function (e) { 
    var check = e.detail.passback; 
    // [do what you need to here]. 
}); 
+1

这是一个很好的解决方案,在我看来。但请注意,不推荐使用“initCustomEvent”。相反,您可以使用“CustomEvent”构造函数。来源:https://developer.mozilla。org/en-US/docs/Web/API/CustomEvent/initCustomEvent – Luoruize

+0

我得到一个'Uncaught TypeError:“)();”不是函数错误。这个解决方案是否仍然有效? –

+1

它实际上是通过传递一个多行字符串来工作的:'scr.textContent ='' var event = document.createEvent(“CustomEvent”); event.initCustomEvent(“MyCustomEvent”,true,true,{“passback”:token}); window.dispatchEvent(event); \';' –