如何运行脚本与自定义全局上下文在Firefox chrome浏览器

How to run script with custom global context in Firefox chrome?

本文关键字:上下文 全局 Firefox 浏览器 chrome 自定义 何运行 运行 脚本      更新时间:2023-09-26

我正在尝试创建与一些网页的DOM工作的扩展。

我有一个代码:

document.getElementById("appcontent").addEventListener("DOMContentLoaded", function(e) {
    _this._onPageLoad(e);
}, true);

但在_onPageLoad函数我的全局上下文是全局窗口(ChromeWindow),而不是一个窗口与我的网页。我如何运行_onPageLoad与全局上下文的窗口,其中事件被触发(网页)和传递参数在这里?

谢谢。

嗯,覆盖脚本运行在顶层窗口的上下文中,即ChromeWindow .

然而,你在某种程度上模拟了另一个上下文。

_this._onPageLoad = function(window, document, e) {
  // Called as .call(window, window, window.document, e);
  // this === window === <content window>
  // document === <content document>
}; 
document.getElementById("appcontent").addEventListener("DOMContentLoaded", function(e) {
    let win = e.originalTarget;
    if (win.ownerDocument) {
      win = win.ownerDocument;
    }
    if (win.defaultView) {
      win = win.defaultView;
    }
    _this._onPageLoad.call(win, win, win.document, e);
}, true);

这将调用您的_onPageLoad与适当的this, windowdocument属于事件指示负载的文档。但是,该方案不会真正重置全局,因此addEventListener仍然会引用顶级窗口。此外,脚本不会在沙箱中运行,并且仍然具有完整的权限。因此,最后,这只是增加了一点方便。

也可以设置和使用真正的Sandbox,但这有点复杂。基本思想是选择适当的主体(完全特权或内容特权),构建沙盒并提供内容窗口作为sandboxPrototype和调用.evalInSandbox(...)。这或多或少是SDK内部做的内容脚本…然而,这通常是多余的,除非你需要一个真正的和适当的安全边界(例如需要执行用户提供的或远程脚本)。

我的解决方案:

Lpr2.prototype._evalInSandbox = function(script, doc, data) {
    var sandbox = new Components.utils.Sandbox(doc.defaultView);
    sandbox.unsafeWindow = doc.defaultView.window.wrappedJSObject;
    sandbox.window = doc.defaultView.window;
    sandbox.document = sandbox.window.document;
    sandbox.__proto__ = sandbox.window;
    var functionName = 'execute_' + script.name;
    var functionText = 'function ' + functionName + script.run.toString().substring(8);
    functionText += '; window.lpr2data = ' + JSON.stringify(data) + '; ' + functionName + '(window, document, Zepto);';
    Services.scriptloader.loadSubScript('chrome://*/content/lib/zepto.min.js', sandbox, 'UTF–8');
    Components.utils.evalInSandbox(functionText, sandbox);
}

很糟糕,但这对我来说只是一个可行的解决方案