【问题标题】:Chrome Extension - access document/page variable from extensionChrome 扩展程序 - 从扩展程序访问文档/页面变量
【发布时间】:2014-02-12 15:06:36
【问题描述】:

我正在尝试开发仅适用于指定页面的扩展 - 如果页面所有者将全局变量添加到他们的代码中(例如,ACCEPT_STATS = true;)我想执行指定的代码。

我已经将我的函数绑定到 onload 事件,我还找到了如何在 Firefox 中执行此操作的解决方案:

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

但我无法在 Chrome 下完成这项工作。是否有可能访问文档的全局变量 throw Chrome 扩展代码?

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

【问题讨论】:

  • 这听起来像是内容脚本应该做的事情,不是吗? developer.chrome.com/extensions/content_scripts.html
  • “但是,内容脚本有一些限制。它们不能:[...]使用由网页或其他内容脚本定义的变量或函数”
  • 内容脚本在一个孤立的世界中执行。您必须将代码注入页面。
  • 是的,这就是问题所在。我搜索提供了全局 JS 变量的网站,并想测试指定页面是否包含它。
  • 好吧,但是只要网页正在监听,就可以使用 window.postMessage 在内容脚本和网页之间进行通信。但不听我认为没有机会,因为它违反了安全政策

标签: javascript google-chrome google-chrome-extension


【解决方案1】:

是的,在页面中包含脚本确实在与页面运行时脚本隔离的上下文中运行。

但是,可以通过附加到文档 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].
});

【讨论】:

  • 在我看来,这是一个很好的解决方案。但是请注意,“initCustomEvent”已被弃用。相反,您可以使用“CustomEvent”构造函数。来源:developer.mozilla.org/en-US/docs/Web/API/CustomEvent/…
  • 我收到Uncaught TypeError: ")();" is not a function 错误。这个解决方案还应该有效吗?
  • 它实际上是通过传递一个多行字符串来工作的:scr.textContent = ` var event = document.createEvent("CustomEvent"); event.initCustomEvent("MyCustomEvent", true, true, {"passback": token}); window.dispatchEvent(event); `;
【解决方案2】:

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

实现这一点的正确方法是通过 window.postMessage API 与页面通信。以下是我的处理方式:

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

HTH

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-11-20
    • 1970-01-01
    • 1970-01-01
    • 2014-05-29
    • 1970-01-01
    • 2016-09-13
    • 2010-11-29
    相关资源
    最近更新 更多