"Un-redefining" Объект консоли Google Chrome

Я имею дело с системой, в которой следующий код 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() {}
}

Этот код используется для создания объекта mock console для предотвращения ошибок JavaScript в средах без консоли javascript. Это замечательно, за исключением того, что он также запрещает запуск консоли Google Chrome. Условное выражение явно проверяет firebug, но что оно

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

Итак, есть ли способ сказать отладчику Chrome повторно инициализировать свой консольный объект? То есть, простым английским языком, сообщите Chrome

Эй, вы знаете, когда загружаете страницу и определяете для меня консольный объект? Сделайте это снова, чтобы мы могли переопределить то, что сделал пользователь в пространстве пользователя.

Я понимаю, что могу сделать что-то вроде

console.firebug = "faketrue";

и у вас есть условный захват, но я ограничен в системе и не имею возможности добавить javascript перед вышеупомянутыми ударами переопределения консоли. Другими словами, нет, я не могу просто добавить немного кода javascript сразу после начала главы.

Ответы

Ответ 1

Я считаю, что вы могли бы сделать это с помощью 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>

Ответ 2

В Google Chrome удаляется объект console:

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

Однако, похоже, это не работает в Firefox 4. Однако это начало.

Ответ 3

Это работает:

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

Однако похоже, что вы не можете удалить iframe

Ответ 4

Вы можете написать довольно простой пользовательский текст, чтобы назначить консоль, как было предложено выше. Затем зайдите в manifest.json для этого usercript и измените параметр run_at (см. http://code.google.com/chrome/extensions/content_scripts.html) на document_start. Это приведет к тому, что usercript будет запущен до запуска любого из скриптов страниц, поэтому до того, как консоль когда-либо запутается.

... редактировать...

Собственно, я отмечаю из http://blog.chromium.org/2011/07/chrome-extensions-now-with-more.html, что хром теперь поддерживает @run-at, поэтому вы можете установить это и не выполнять даже придется напрямую входить с manifest.json. Они имеют пример script, используя @run-at на document_start в http://src.chromium.org/viewvc/chrome/trunk/src/chrome/common/extensions/docs/examples/howto/userscript-runat/runat.user.js?view=markup

Ответ 5

Не можете ли вы поместить свой собственный script прямо в голову html справа вверху?

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

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

Вы не можете получить гораздо раньше, чем прямо в HEAD.

Ответ 6

Предполагая, что причина в том, что вы хотите использовать консоль, как правило, при разработке, вы можете взломать простое расширение chrome, которое определяет console.firebug, чтобы условие оценивалось как false. Таким образом, вам не нужно беспокоиться о каком-либо потенциальном причудливом поведении, которое может возникнуть в результате использования какого-либо другого объекта консоли консоли, а также не нужно беспокоиться о том, чтобы многократно вставлять и удалять хак при разработке/развертывании.