“取消重新定义”Google Chrome的控制台对象

时间:2011-05-25 22:18:00

标签: javascript google-chrome google-chrome-devtools

我正在处理一个系统,其中在页面的早期正在执行以下Javascript代码(我无法控制)

if (!("console" in window) || !("firebug" in console))
{
    var names = ["log", "debug", "info", "warn", "error", "assert", "dir", "dirxml",
    "group", "groupEnd", "time", "timeEnd", "count", "trace", "profile", "profileEnd"];
    window.console = {};
    for (var i = 0; i < names.length; ++i)
        window.console[names[i]] = function() {}
}

此代码似乎用于创建模拟console对象,以防止在没有javascript控制台的环境中出现javascript错误。这很棒,但它也阻止了谷歌Chrome控制台的运行。条件明确地检查firebug,但就是它

    if (!("console" in window) || !("firebug" in console))

那么,有没有办法告诉Chrome的调试器重新初始化其控制台对象?也就是说,用简单的英语告诉Chrome

  

嘿,你知道当你加载一个页面并定义一个控制台对象供我使用吗?再次这样做,以便我们可以覆盖用户空间中的某个人所做的事情。

我意识到我可以做类似

的事情
console.firebug = "faketrue";

并且有条件捕获,但我在系统中受到限制,并且在上述控制台重新定义命中之前没有办法添加javascript。换句话说,不,我不能在头部开始后立即添加一些javascript代码。

7 个答案:

答案 0 :(得分:16)

我相信你可以用iframe注入然后复制iframe的控制台对象:

<script type="text/javascript">
console = {};
try {
    console.log('1');
} catch(e){
    alert('No console');
}
</script>
<iframe id="text"></iframe>
<script type="text/javascript">
console = window.frames[0].console;
try {
    console.log('test');
} catch(e){
    alert('No console');
}
</script>

http://jsfiddle.net/nmY6k/

请注意,这只是该概念应该有效的证明。

修改

使用纯JS iframe:

<script type="text/javascript">
console = {};
try {
    console.log('1');
} catch(e){
    alert('No console');
}
var iframe = document.createElement('iframe');
document.body.appendChild(iframe);
console = window.frames[0].console;
try {
    console.log('test');
} catch(e){
    alert('No console');
}
</script>

http://jsfiddle.net/nmY6k/1/

修改

当然,如果您之后需要删除iframe元素:

<script type="text/javascript">
console = {};
try {
    console.log('1');
} catch(e){
    alert('No console');
}
var iframe = document.createElement('iframe');
document.body.appendChild(iframe);
console = window.frames[0].console;
try {
    console.log('test');
} catch(e){
    alert('No console');
}
console.log(typeof window.frames);
document.body.removeChild(iframe);
console.log(typeof window.frames);
</script>

答案 1 :(得分:3)

在谷歌浏览器中,删除console对象有效:

<script>
window.console = {};
delete console;
console.log('still works');
</script>

然而,这似乎在Firefox 4中不起作用。但这是一个开始。

答案 2 :(得分:1)

这似乎有效:

iframe = document.createElement('iframe');
document.body.appendChild(iframe);
console = iframe.contentWindow.console;

但是,您似乎无法删除iframe

答案 3 :(得分:1)

您可以编写一个非常基本的用户脚本来分配控制台,如上所述。然后进入该用户脚本的manifest.json,并将run_at设置(请参阅http://code.google.com/chrome/extensions/content_scripts.html)更改为document_start。这将使用户脚本现在在任何页面脚本运行之前运行,因此在控制台变得混乱之前。

...编辑...

实际上,我从http://blog.chromium.org/2011/07/chrome-extensions-now-with-more.html注意到chrome现在也支持@ run-at,所以你可以设置它,甚至不必直接搞乱manifest.json。他们在http://src.chromium.org/viewvc/chrome/trunk/src/chrome/common/extensions/docs/examples/howto/userscript-runat/runat.user.js?view=markup

的document_start上使用了@ run-at的示例脚本

答案 4 :(得分:0)

你不能把你自己的脚本直接放在顶部的html头部吗?

<script ...>
    if (console) { window.cache_console = console; }
</script>
</head>
<body>
... html ...

<script>
    window.console = window.cache_console;
</script>
</body>
</html>

你不能比HEAD早得多。

答案 5 :(得分:0)

假设您担心的原因是您希望在开发时正常使用控制台,那么您可以创建一个简单的chrome扩展来定义console.firebug,以便条件评估为false。这样您就不必担心使用其他框架的控制台对象可能产生的任何潜在奇怪行为,也不必担心在开发/部署时反复插入和删除黑客。

答案 6 :(得分:0)

这是我根据先前的答案写的一种方法。它具有一些额外的逻辑,因此您可以多次调用它,而无需重新创建iframe。

function fixConsole() {

    var iframe;
    if(!(iframe = document.getElementById('fixConsole'))) {
        iframe = document.createElement('iframe');
        iframe.id = 'fixConsole';
        document.body.appendChild(iframe);
    }
    delete console;    
    console = iframe.contentWindow.console;

};

在最初重新定义fixConsole的代码是自修复的情况下,我预计需要多次调用console