背景
Greasemonkey 不是已经注入了我的扩展 JavaScript 吗?有人可以帮我澄清一下吗?
Greasemonkey 在中执行您的脚本sandbox,这是一个受限环境,无法直接访问页面中的 JavaScript。 Greasemonkey 的早期版本直接将脚本注入到页面中,但这引入了严重的安全漏洞。在旧模型中,脚本以浏览器 chrome 的提升权限运行,这允许远程页面使用一些命令来访问 Greasemonkey 的内置功能。聪明的JavaScript。这很糟糕:
Greasemonkey 脚本包含自己的 GM_xmlhttprequest 对象,与普通的 xmlttprequest 对象不同,该对象可以访问计算机上的任何本地文件或向任意站点发出任意请求,而不考虑通常适用于 xmlhttprequest 的同源策略。(source)
当您访问window
今天从 Greasemonkey 脚本中获取对象,你得到的是包装对象间接引用实际的window
的属性。这个包装对象可以安全地修改,但是有重要的限制。对实际窗口对象的访问由unsafeWindow(简写为window.wrappedJSObject
)。用于unsafeWindow
重新打开了 Greasemonkey 的所有原始安全问题,并且在 Chrome 中不可用。应尽可能避免。
好消息:至少有两种方法可以安全地使用 Greasemonkey 的新安全模型。
脚本注入
现在 Greasemonkey 脚本可以安全地访问 DOM,接下来就很简单了注入一个<script>标记到<head>
目标文档的。创建一个像这样的函数:
function exec(fn) {
var script = document.createElement('script');
script.setAttribute("type", "application/javascript");
script.textContent = '(' + fn + ')();';
document.body.appendChild(script); // run the script
document.body.removeChild(script); // clean up
}
使用起来很简单:
exec(function() {
return Grooveshark.playNextSong();
});
位置黑客
在某些情况下,脚本注入可能有点过头了,特别是当您只需要修改页面中变量的值或执行单个函数时。这位置黑客杠杆javascript:
用于访问文档内容中的代码的 URL。这很像在 Greasemonkey 脚本中运行书签。
location.assign("javascript:Grooveshark.playNextSong();void(0)");
奖金脚本
这是一个完整的 Greasemonkey 脚本,演示了上面的示例。您可以在此页面上运行它。
// ==UserScript==
// @name Content Function Test
// @namespace lwburk
// @include http://stackoverflow.com/questions/5006460/userscripts-greasemonkey-calling-a-websites-javascript-functions
// ==/UserScript==
function exec(fn) {
var script = document.createElement('script');
script.setAttribute("type", "application/javascript");
script.textContent = '(' + fn + ')();';
document.body.appendChild(script); // run the script
document.body.removeChild(script); // clean up
}
window.addEventListener("load", function() {
// script injection
exec(function() {
// alerts true if you're registered with Stack Overflow
alert('registered? ' + isRegistered);
});
// location hack
location.assign("javascript:alert('registered? ' + isRegistered);void(0)");
}, false);