我在开发这个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}}元素不同。有人能解释我为什么吗?
答案 0 :(得分:47)
见"Are Chrome user-scripts separated from the global namespace like Greasemonkey scripts?"。 Chrome用户脚本/内容脚本和Greasemonkey脚本都与页面的javascript隔离。这样做是为了帮助您避免被黑客攻击,但它也可以减少冲突和意外的副作用。
但是,每个浏览器的方法都不同......
<强>火狐:强>
@grant none
生效(从GM 1.0开始)。unsafeWindow
来访问目标网页的javascript。但请注意,敌对网站管理员可能将unsafeWindow
用法追溯到脚本的上下文中,从而获得提升权限,以便与您合作。<强>铬:强>
unsafeWindow
的对象,但兼容性非常有限,但此对象不提供对目标页面JS的任何访问。它与脚本范围中的window
相同(页面范围中不是window
)。也就是说,如果正确实现,使用unsafeWindow
的脚本版本应该在Firefox中使用。 可能在Chrome上使用the Tampermonkey extension工作,但我现在不打算再仔细检查。
当您执行“技巧”(var script = document.createElement("script"); ...
)时,您 将 代码注入目标网页。这绕过了沙箱,是普通Chrome用户脚本与脚本JS进行交互的唯一方式。
注射优势:
注射缺陷:
脚本(至少是注入的部分)无法使用GM_
函数提供的增强权限(尤其是跨域) - 尤其是GM_xmlhttpRequest()
。
请注意,目前 Chrome仅完全支持GM_addStyle
,GM_xmlhttpRequest
,GM_log
和GM_openInTab
。
但是,Tampermonkey几乎完全支持GM_
个功能。
可能会导致副作用或与页面的JS冲突。
使用外部库会引入更多冲突和时序问题。它远不如@require
那么容易
@require
,也从本地副本运行外部JS - 加快执行速度,但几乎不再依赖外部服务器。
该页面可以查看,使用,更改或阻止脚本。
需要启用JS。特别是Firefox Greasemonkey可以在JS被阻止的页面上运行。这可能是臃肿,蹩脚和/或侵入性页面的天赐。