如何在最新的Firefox WebExtension中放弃Xrays的愿景?

时间:2017-05-02 07:04:08

标签: firefox-webextensions

我正在关注指南here

我想放弃Xrame对iframe的看法:

var foo = $(Components.utils.waiveXrays($("#foobar").get(0).contentWindow.document));

以上内容在manifest.json的内容脚本中运行,如下所示:

  "content_scripts": [
    {
      "matches": /* something */,
      "css": ["content.css"],
      "js": ["jquery-3.2.1.js","content.js"]
    }
  ]

但是我会得到一个未定义的对象错误:

[firefox/index.js][debug] Firefox stderr: JavaScript error: , line 0: Error: Components.utils is undefined

我认为Mozilla网站上的指南已经过时。它不适用于纯WebExtension实现。

现在应该采用哪种正确的最新方法?

2 个答案:

答案 0 :(得分:2)

经过几天的研究(并在mozilla firefox邮件列表中询问)。我已经找到了解决方案。正确的指南是here(截至2017年5月14日):

  

在SDK中,内容脚本可以使用页面脚本共享对象   unsafeWindow和createObjectIn等技术。在WebExtensions中   unsafeWindow可以通过wrappedJSObject来获得。全部出口   帮助函数也可用。

如果我想访问窗口对象的放弃xrays版本,我应该使用:

window.wrappedJSObject

如果页面中有iframe,我想访问其中的对象。这是其中一种方式:

document.getElementById("the_iframe").contentWindow.wrappedJSObject

但是,我发现如果iframe位于跨域,则无法访问wrappedJSObject (从Firefox版本51.0.1开始)。我需要寻找另一种方法如下:

提供一个内容脚本,该脚本会注入所有子iframe,然后实现一个后台脚本,在子iframe和首页之间提供messaging bridge

  "background": {
    "scripts": ["background.js"]
  },

  "content_scripts": [
    {
      "matches": ["*://*.something"],
      "css": ["content.css"],
      "all_frames": true, /* ADD THIS LINE */
      "js": ["jquery-3.2.1.js","content.js"]
    }
  ]

在content.js中,做一些类似的事情:

if(window.top == window.self) { // main
  main();
}
else if(window.name == "frameA") { // match frameA
  browser.runtime.onMessage.addListener(function(msg) {
    /* Check the message msg and then access the waived X rays vision by window.wrappedJSObject */
     if(msg matches something) {
       var ret = window.wrappedJSObject.foobar(msg.data);
       /* Send back the return value to background.js by browser.runtime.sendMessage */
       browser.runtime.sendMessage({"returnVal": ret, "from": "frameA"}); 
     }
    }
  });
}

在background.js中,进行一些消息转发:

function forward_to_all(r)
{
  var forwardMessage = function(tabs) {
    for(let tab of tabs) {
      browser.tabs.sendMessage(tab.id,r);
    }
  }
  browser.tabs.query({currentWindow:true, active:true}).then(forwardMessage);
}
browser.runtime.onMessage.addListener(function(msg) {
  if(msg matches something) {
    forward_to_all(msg);
  }
});

答案 1 :(得分:0)

你并不意味着能够在firefox webextensions中放弃xrays,如果你能够那么它就会很快被禁用。

  

我认为Mozilla网站上的指南已经过时了。

确实

  

现在应该采用哪种正确的最新方法?

你想做什么(即放弃xray包装)是不可能的。可能最好考虑一种新方法来实现你想要的东西,不管是什么(我不能通过描述来说明)。