如何在Chrome中模仿Greasemonkey/Firefox的unsafeWindow功能?

7
我现在正在尝试使用Chrome的用户脚本,所以请容忍我的潜在无知/愚蠢。
在我编写脚本的页面中,有一个<script>元素声明了一个变量x。这意味着,在我的用户脚本中,我可以从全局命名空间访问x吗?
例如,如果我用户脚本的唯一一行是alert(x);,那么是否应该按预期工作(假设x是一个字符串)?我知道Chrome不支持unsafewindow,但由于某种原因,我发现很难模仿这个功能。这可行吗?
5个回答

13

这将给您一个指向窗口对象的引用(作为p):

var p = unsafeWindow;

if(window.navigator.vendor.match(/Google/)) {
    var div = document.createElement("div");
    div.setAttribute("onclick", "return window;");
    p = div.onclick();
};

6
不需要进行“供应商嗅探”,你可以像这样做:https://gist.github.com/1143845 - Mathias Bynens
8
在最新版的Chrome中,似乎这个不再起作用了。 - uınbɐɥs

11

更新:
最新版本的Chrome浏览器中,onclick漏洞已经无法使用。

想要在Chrome中使用unsafeWindow功能,最好的方法是安装和使用Tampermonkey——不管怎样都会很明智。 Tampermonkey具有对Greasemonkey API的完全支持和更加简便的脚本管理功能。

Greasemonkey脚本和Tampermonkey脚本几乎总是完全兼容,而这对于普通的Chrome用户脚本并非如此。

如果不使用Tampermonkey,唯一仍然有效的替代方法就是使用某种形式的script injection



以下内容已经过时:

现在Chrome为用户脚本/内容脚本定义了unsafeWindow, 但是Chrome的unsafeWindow仍然不允许访问目标页面创建的JS对象。

以下是如何以跨浏览器的方式提供一个适当的不安全的unsafeWindow -- 使用特性检测(好)而不是浏览器嗅探(坏)

/*--- Create a proper unsafeWindow object on browsers where it doesn't exist
    (Chrome, mainly).
    Chrome now defines unsafeWindow, but does not give it the same access to
    a page's javascript that a properly unsafe, unsafeWindow has.
    This code remedies that.
*/
var bGreasemonkeyServiceDefined     = false;

try {
    if (typeof Components.interfaces.gmIGreasemonkeyService === "object") {
        bGreasemonkeyServiceDefined = true;
    }
}
catch (err) {
    //Ignore.
}

if ( typeof unsafeWindow === "undefined"  ||  ! bGreasemonkeyServiceDefined) {
    unsafeWindow    = ( function () {
        var dummyElem   = document.createElement('p');
        dummyElem.setAttribute ('onclick', 'return window;');
        return dummyElem.onclick ();
    } ) ();
}

这还有效吗?我在Chrome中尝试覆盖XHR发送,但似乎没有任何作用。我只是添加了:var oldSend = unsafeWindow.XMLHttpRequest.prototype.send; unsafeWindow.XMLHttpRequest.prototype.send = function(){ console.log("notified of XHR update"); oldSend.apply(this, arguments); } 但是在请求期间我没有输出。如果我将此代码注入页面,则会产生输出。 - mix
@Mix,是的,我刚刚验证了它在Chrome 18版本和19版本(19.0.1084.56 m)上仍然有效。请为您的问题开一个新的问题。 - Brock Adams
@user280109,是的,Chrome已经修复了那个漏洞。你应该安装和使用Tampermonkey。否则,你将不得不使用脚本注入。 - Brock Adams
ViolentMonkey在Chrome中也是一个选择,而且是开源的,所以我更推荐它而不是TamperMonkey。非常感谢你提供详细的答案!我已经试了很长时间都没弄明白。 - Wyatt Ward

9

contentWindow在Chrome 3中可用,但在Chrome 4中被删除。Chrome 4的唯一可能解决方案是:

location.href="javascript:(function(){ alert('Hello'); })()"

1
如果你想与页面JavaScript交互,你需要将一个脚本插入到页面中。(当然,除非你想使用此页面建议的任何黑客方法。)我已经为自己的脚本编写了一个函数来完成这个任务,我会在这里发布它,以便任何人都可以使用。
/*
    @description    This function will insert the given code as a <script> or <style> block into a page.
    @param The code to insert; supported types are: JavaScript Function, String (JavaScript), String (CSS).
    @param2 Optional: The type of code that is inserted. If omitted, "js" is assumed. Possible values are 'js' or 'css'.
    @return The HTML element that was inserted, or FALSE on failure
*/
function insert(z,t){
    var j,f,x,c,i,n,d
    d=document
    c=d.createElement
    i=d.head.appendChild
    a=d.createTextNode
    if(typeof z==='function') j=!0,f=!0;
    if((t=='js'||!t)&&!f){j=!0,f=!1}
    if(t=='css'&&!j){x=c('style');x.setAttribute('type','text/css')}
    if(j){x=c('script');x.setAttribute('type','text/javascript')}
    if(f) n=a('('+z+')()');else n=a(z)
    x.appendChild(n)

    if(x){return i(x)}else{return !1}
}

以下是一些例子,以便澄清:

//Inserting a JavaScript function
var func=function(){
    stopAds();
    startFileDownload();
}

insert(func);


//Inserting JavaScript as a string
var strJS="prompt(\"Copy:\",someVariableAtThePage);";

insert(strJS);
//Or with an OPTIONAL 2nd parameter:
insert(strJS,'js');


//Inserting CSS
var strCSS=".ad{display:none !important}    #downloadButton{display:block}";

insert(strCSS,'css');//Specifying 2nd parameter as "css" is required.

0

好的,这里有一个想法,你可以使用地址栏注入脚本...

javascript:var ElEm = document.createElement("script");ElEm.src='[path_to_script]';document.body.appendChild(ElEm);

然后你可以使用JavaScript在窗口中运行任何你想要的东西


哦,如果变量是页面全局的,你应该能够用你的JavaScript读取它。 - Carter Cole

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接