“Un-redefining” Google Chrome's console Object

余生长醉 提交于 2019-11-30 08:45:43

I believe you could possibly do this with an iframe inject and then copy the iframe's console object:

<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/

Note, this is just a demonstration that the concept should work.

EDIT

With a pure 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/

EDIT

And of course, if you need to remove the iframe element afterwards:

<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>

In Google Chrome, deleting the console object works:

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

However, this doesn't seem to work in Firefox 4. It's a start, though.

This seems to work:

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

However it looks like you cannot remove the iframe

You could write a pretty basic userscript to assign console as suggested above. Then go into the manifest.json for that userscript, and change the run_at setting (see http://code.google.com/chrome/extensions/content_scripts.html ) to document_start. That will make the userscript now run before any of the page scripts run, so before console ever gets messed with.

...edit...

Actually, I note from http://blog.chromium.org/2011/07/chrome-extensions-now-with-more.html that chrome also now supports @run-at, so you can set that, and don't even have to mess with manifest.json directly. They have an example script using @run-at at document_start at http://src.chromium.org/viewvc/chrome/trunk/src/chrome/common/extensions/docs/examples/howto/userscript-runat/runat.user.js?view=markup

Can't you put your own script directly in the head of the html right at the top?

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

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

You can't get much earlier than right up in the HEAD.

Assuming the reason you're concerned is that you want to use the console normally as you develop, you could whip up a simple chrome extension that defines console.firebug so that the condition will evaluate to false. That way you don't need to worry about any potential quirky behavior that might arise from using some other frame's console object, nor do you have to worry about repeatedly inserting and deleting a hack as you develop/deploy.

Here is a method I wrote based on the previous answers. It's got a bit of extra logic so that you can call it multiple times without recreating the 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;

};

I anticipate the need to call fixConsole multiple times in the case that the code which originally redefined console is self repairing.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!