为什么window(和unsafeWindow)与用户脚本和<script>标签不一样?</script>

时间:2012-05-30 21:44:46

标签: javascript greasemonkey scope userscripts

我在开发这个small userscript时遇到了一个问题。当我想用我的脚本阻止正在运行的网站中的每个XMLHttpRequest时,没有任何事情发生(至少在Chrome上):

function main() {
  // Override XHR.open with a custom function
  window.XMLHttpRequest.prototype.open = function() {
    // Nothing... so it's supposed to block every xhr.open() call
  }
}
main();

window替换unsafeWindow时也是如此。

然而,当我使用这个小技巧时,一切都像魅力一样:

// No more call to main(), and:
var script = document.createElement("script");
script.textContent = "(" + main.toString() + ")();";
document.body.appendChild(script);

xhr.open的每次调用都被我的自定义函数替换,不再是AJAX。

因此,当从脚本内部调用window时,main元素与从<script></script>容器调用{{1}}时的{{1}}元素不同。有人能解释我为什么吗?

1 个答案:

答案 0 :(得分:47)

"Are Chrome user-scripts separated from the global namespace like Greasemonkey scripts?"。 Chrome用户脚本/内容脚本和Greasemonkey脚本都与页面的javascript隔离。这样做是为了帮助您避免被黑客攻击,但它也可以减少冲突和意外的副作用。

但是,每个浏览器的方法都不同......

<强>火狐:

  1. an XPCNativeWrapper sandbox中运行脚本,除非@grant none生效(从GM 1.0开始)。
  2. 默认情况下在匿名函数中包装脚本。
  3. 提供unsafeWindow来访问目标网页的javascript。但请注意,敌对网站管理员可能unsafeWindow用法追溯到脚本的上下文中,从而获得提升权限,以便与您合作。
  4. <强>铬:

    1. an "isolated world"中运行脚本。
    2. 以匿名函数包装脚本。
    3. 严格 阻止脚本对页面JS的任何访问,反之亦然。
      最近版本的Chrome现在提供了一个名为unsafeWindow的对象,但兼容性非常有限,但此对象不提供对目标页面JS的任何访问。它与脚本范围中的window相同(页面范围中不是window)。

    4. 也就是说,如果正确实现,使用unsafeWindow的脚本版本应该在Firefox中使用。 可能在Chrome上使用the Tampermonkey extension工作,但我现在不打算再仔细检查。

      当您执行“技巧”(var script = document.createElement("script"); ...)时,您 代码注入目标网页。这绕过了沙箱,是普通Chrome用户脚本与脚本JS进行交互的唯一方式。

      注射优势:

      1. 非Tampermonkey用户脚本访问目标页面提供的对象或功能的唯一方法。
      2. Chrome,Firefox,Opera等几乎总是完全兼容(IE就像往常一样。)
      3. 通常更容易调试整个脚本;开发人员工具正常工作。
      4. 注射缺陷:

        1. 脚本(至少是注入的部分)无法使用GM_函数提供的增强权限(尤其是跨域) - 尤其是GM_xmlhttpRequest()。 请注意,目前 Chrome仅完全支持GM_addStyleGM_xmlhttpRequestGM_logGM_openInTab。 但是,Tampermonkey几乎完全支持GM_个功能。

        2. 可能会导致副作用或与页面的JS冲突。

        3. 使用外部库会引入更多冲突和时序问题。它远不如@require那么容易 @require,也从本地副本运行外部JS - 加快执行速度,但几乎不再依赖外部服务器。

        4. 该页面可以查看,使用,更改或阻止脚本。

        5. 需要启用JS。特别是Firefox Greasemonkey可以在JS被阻止的页面上运行。这可能是臃肿,蹩脚和/或侵入性页面的天赐。