Что случилось с console.log в IE8?

254

Согласно этому посту это было в бета-версии, но это не в релизе?

leeand00
источник
65
console.log находится там в IE8, но consoleобъект не не создается , пока вы раскрываете Devtools. Поэтому обращение к console.logможет привести к ошибке, например, если это происходит при загрузке страницы до того, как вы сможете открыть инструменты разработки. Победы ответ здесь объясняет это более подробно.
SDC

Ответы:

229

Еще лучше для отступления это:


   var alertFallback = true;
   if (typeof console === "undefined" || typeof console.log === "undefined") {
     console = {};
     if (alertFallback) {
         console.log = function(msg) {
              alert(msg);
         };
     } else {
         console.log = function() {};
     }
   }

jpswain
источник
71
Это настолько непрактично - как вы могли бы отлаживать сайт с помощью чего-то, что выдает предупреждение при каждом вызове console.log (). Что делать, если у вас есть 10+ звонков в log () в вашем коде. Что если msg это объект? Ответ Уолтера имеет гораздо больше смысла, как отправная точка.
Precastic
7
@Precastic: Люди просто перестанут пользоваться браузером: P
Amogh Talpallikar
Смотрите мой комментарий к ответу мистера Лаки.
Даниэль Шиллинг
1
ненавязчивым (хотя и несовершенным) альтернативным вариантом является установка document.title. По крайней мере, это не блокирует браузер модальным предупреждением.
brennanyoung
257

console.log доступен только после того, как вы открыли Инструменты разработчика (F12 для переключения его открытия и закрытия). Забавно, что после того, как вы открыли его, вы можете закрыть его, а затем отправлять в него сообщения с помощью вызовов console.log, и они будут видны при повторном открытии. Я думаю, что это своего рода ошибка, и может быть исправлена, но посмотрим.

Я, вероятно, просто буду использовать что-то вроде этого:

function trace(s) {
  if ('console' in self && 'log' in console) console.log(s)
  // the line below you might want to comment out, so it dies silent
  // but nice for seeing when the console is available or not.
  else alert(s)
}

и даже проще:

function trace(s) {
  try { console.log(s) } catch (e) { alert(s) }
}
Мистер Лаки
источник
11
В любом случае вы не должны вызывать console.log вслепую, потому что $ other-browser может его не иметь и, следовательно, умрет с ошибкой JavaScript. +1
Кент Фредрик
8
вы, вероятно, все равно захотите отключить следы перед выпуском;)
Кент Фредрик,
2
Имеет смысл не входить в систему, если инструменты разработчика не открыты, а заставлять их выдавать исключение, если вместо того, чтобы молча терпеть неудачу, это действительно запутанное решение.
EHDV
4
Я хочу указать на обратную сторону обёртывания console.log следующим образом ... вы больше не увидите, откуда взялись ваши логи. Я считаю, что иногда очень полезно, что кажется неправильным, когда каждая строка консоли происходит из одного и того же места в вашем коде.
Мартин Уэстин
2
alertэто зло Некоторые коды ведут себя по-разному, когда используются оповещения, потому что документ теряет фокус, что затрудняет диагностику ошибок или создает ошибки там, где их раньше не было. Кроме того, если вы случайно оставите a console.logв своем производственном коде, он будет доброкачественным (при условии, что он не взорвется) - просто тихо войдет в консоль. Если вы случайно оставите alertв своем производственном коде пользовательский опыт разрушен.
Даниэль Шиллинг
56

Это мой взгляд на разные ответы. Я действительно хотел видеть зарегистрированные сообщения, даже если у меня не было открытой консоли IE, когда они были запущены, поэтому я помещаю их в console.messagesсозданный мной массив. Я также добавил функцию console.dump()для облегчения просмотра всего журнала. console.clear()очистит очередь сообщений.

Это решение также «обрабатывает» другие методы консоли (которые, я считаю, все происходят из API консоли Firebug )

Наконец, это решение имеет форму IIFE , поэтому оно не загрязняет глобальный масштаб. Аргумент резервной функции определяется в нижней части кода.

Я просто помещаю его в свой основной файл JS, который есть на каждой странице, и забываю об этом.

(function (fallback) {    

    fallback = fallback || function () { };

    // function to trap most of the console functions from the FireBug Console API. 
    var trap = function () {
        // create an Array from the arguments Object           
        var args = Array.prototype.slice.call(arguments);
        // console.raw captures the raw args, without converting toString
        console.raw.push(args);
        var message = args.join(' ');
        console.messages.push(message);
        fallback(message);
    };

    // redefine console
    if (typeof console === 'undefined') {
        console = {
            messages: [],
            raw: [],
            dump: function() { return console.messages.join('\n'); },
            log: trap,
            debug: trap,
            info: trap,
            warn: trap,
            error: trap,
            assert: trap,
            clear: function() { 
                  console.messages.length = 0; 
                  console.raw.length = 0 ;
            },
            dir: trap,
            dirxml: trap,
            trace: trap,
            group: trap,
            groupCollapsed: trap,
            groupEnd: trap,
            time: trap,
            timeEnd: trap,
            timeStamp: trap,
            profile: trap,
            profileEnd: trap,
            count: trap,
            exception: trap,
            table: trap
        };
    }

})(null); // to define a fallback function, replace null with the name of the function (ex: alert)

Некоторая дополнительная информация

Линия var args = Array.prototype.slice.call(arguments);создает массив из argumentsобъекта. Это необходимо, потому что аргументы на самом деле не являются массивом .

trap()является обработчиком по умолчанию для любой из функций API. Я передаю аргументы, чтобы messageвы получили журнал аргументов, которые были переданы любому вызову API (не только console.log).

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

Я добавил дополнительный массив, console.rawкоторый захватывает аргументы в точности так, как передано trap(). Я понял, что args.join(' ')это преобразование объектов в строку, "[object Object]"что иногда может быть нежелательным. Спасибо bfontaine за предложение .

Вальтер Стабош
источник
4
+1 Это единственное решение, которое начинает обретать смысл. В каком мире вы бы не хотели видеть сообщения, которые вы явно отправляете на консоль!
Precastic
Отличный ответ. Очень понравилась статья IIFE, которую вы упомянули, возможно, одна из лучших, которые я читал до сих пор. Не могли бы вы уточнить , что цель этих двух линий в trapфункции: var args = Array.prototype.slice.call(arguments); var message = args.join(' ');? Почему вы передаете аргументы через это сообщение?
user1555863
1
@ user1555863 Я обновил свой ответ, чтобы ответить на ваши вопросы, см. раздел под кодом.
Вальтер Стабош,
1
Я думаю, что вторая строка вашей функции console.clear () должна читать «console.raw.length = 0» вместо «console.row.length = 0».
Стив Дж
52

Стоит отметить, что console.logв IE8 нет настоящей функции Javascript. Он не поддерживает методы applyили call.

Джеймс Уир
источник
3
+1 Это моя точная ошибка сегодня утром. Я пытаюсь применить аргументы к console.log, и IE8 ненавидит меня.
Бернхард Хофманн
[шутка] Microsoft говорит, что «нам небезопасно позволять людям перезаписывать консольный объект»: /
Том Роггеро
1
Я использовал: console.log=Function.prototype.bind.call(console.log,console);чтобы обойти это.
Mowwwalker
1
IE8 не имеет bind.
katspaugh
44

Предполагая, что вам не нужен резерв для оповещения, вот еще более краткий способ обойти недостатки Internet Explorer:

var console=console||{"log":function(){}};
Лейф Викленд
источник
+1 Поскольку я определяю свой код в анонимной функции, размещение консоли в такой переменной является лучшим решением для меня. Помогает мне не вмешиваться в любые другие перехваты консоли, происходящие в других библиотеках.
Codesleuth
2
Вы хотите начать регистрацию, как только инструменты разработчика будут открыты. Если вы поместите это решение в долгоживущую область (например, зарегистрируете внутренние функции как обратные вызовы), оно будет продолжать использовать тихий запасной вариант.
Бени Чернявский-Паскин
+ 1 / -1 = 0: +1, потому что решение должно быть больше основано на предотвращении взлома сайта console.logs в IE - не используется для отладки ... Если вы хотите отладить, просто нажмите f12 и откройте консоль: ) -1, потому что вы должны проверить, существует ли консоль, прежде чем перезаписывать ее.
1
Некоторые плагины IE определяют console и console.log, но как пустые объекты, а не функции.
Река Лилит
24

Мне очень нравится подход, опубликованный "orange80". Это элегантно, потому что вы можете установить его один раз и забыть.

Другие подходы требуют от вас делать что-то другое ( console.log()каждый раз вызывать что-то отличное от простого ), что просто вызывает проблемы ... Я знаю, что в конце концов забуду.

Я сделал еще один шаг, обернув код в служебную функцию, которую вы можете вызвать один раз в начале вашего javascript, где угодно, до того, как он будет записан. (Я устанавливаю это в свой продукт маршрутизатора данных о событиях в моей компании. Это поможет упростить кросс-браузерный дизайн его нового интерфейса администратора.)

/**
 * Call once at beginning to ensure your app can safely call console.log() and
 * console.dir(), even on browsers that don't support it.  You may not get useful
 * logging on those browers, but at least you won't generate errors.
 * 
 * @param  alertFallback - if 'true', all logs become alerts, if necessary. 
 *   (not usually suitable for production)
 */
function fixConsole(alertFallback)
{    
    if (typeof console === "undefined")
    {
        console = {}; // define it if it doesn't exist already
    }
    if (typeof console.log === "undefined") 
    {
        if (alertFallback) { console.log = function(msg) { alert(msg); }; } 
        else { console.log = function() {}; }
    }
    if (typeof console.dir === "undefined") 
    {
        if (alertFallback) 
        { 
            // THIS COULD BE IMPROVED… maybe list all the object properties?
            console.dir = function(obj) { alert("DIR: "+obj); }; 
        }
        else { console.dir = function() {}; }
    }
}
Крис Яницки
источник
1
Рад, что вам это нравится :-) Я использую его именно по той причине, о которой вы упомянули - б / с, это хорошая безопасность. Просто слишком просто поместить некоторые выражения "console.log" в ваш код для разработки и забыть удалить их позже. По крайней мере, если вы сделаете это и поместите его в верхнюю часть каждого файла, в котором вы используете console.log, у вас никогда не будет взлома сайта в браузерах клиентов, поскольку они не работают на console.log. Спас меня раньше! Хорошие улучшения, кстати :-)
jpswain
1
«Просто слишком легко ... забыть удалить их». Одна полезная вещь, которую я всегда делаю с временным ведением журнала отладки, - это добавление кода к пустому комментарию, /**/console.log("...");чтобы легко найти и найти временный код.
Лоуренс Дол
8

Если вы получаете "undefined" для всех ваших вызовов console.log, это, вероятно, означает, что у вас все еще загружен старый firebuglite (firebug.js). Он переопределит все допустимые функции IE8 console.log, даже если они существуют. Это то, что случилось со мной в любом случае.

Проверьте наличие другого кода, переопределяющего объект консоли.

user168290
источник
5

Лучшее решение для любого браузера без консоли:

// Avoid `console` errors in browsers that lack a console.
(function() {
    var method;
    var noop = function () {};
    var methods = [
        'assert', 'clear', 'count', 'debug', 'dir', 'dirxml', 'error',
        'exception', 'group', 'groupCollapsed', 'groupEnd', 'info', 'log',
        'markTimeline', 'profile', 'profileEnd', 'table', 'time', 'timeEnd',
        'timeStamp', 'trace', 'warn'
    ];
    var length = methods.length;
    var console = (window.console = window.console || {});

    while (length--) {
        method = methods[length];

        // Only stub undefined methods.
        if (!console[method]) {
            console[method] = noop;
        }
    }
}());
Винициус Мораес
источник
1
Это имеет явную проблему, что объекты или строки, зарегистрированные с помощью console.group или console.GroupCollapsed, полностью исчезнут. Это не нужно, они должны быть сопоставлены с console.log, если он доступен.
Бен
3

Есть так много ответов. Мое решение для этого было:

globalNamespace.globalArray = new Array();
if (typeof console === "undefined" || typeof console.log === "undefined") {
    console = {};
    console.log = function(message) {globalNamespace.globalArray.push(message)};   
}

Короче говоря, если console.log не существует (или в этом случае не открыт), сохраните журнал в глобальном массиве пространств имен. Таким образом, вам не надоедают миллионы предупреждений, и вы все равно можете просматривать свои журналы при открытой или закрытой консоли разработчика.

calcazar
источник
2
if (window.console && 'function' === typeof window.console.log) {
    window.console.log (о);
}
Балаш Немет
источник
Вы говорите, что window.console.log()может быть доступно в IE8, даже когда console.log()нет?
LarsH
Проблема здесь в том typeof window.console.log === "object", что не"function"
изохронный
2

Вот мой "IE, пожалуйста, не врезаться"

typeof console=="undefined"&&(console={});typeof console.log=="undefined"&&(console.log=function(){});
BrunoLM
источник
1

Я нашел это на GitHub :

// usage: log('inside coolFunc', this, arguments);
// paulirish.com/2009/log-a-lightweight-wrapper-for-consolelog/
window.log = function f() {
    log.history = log.history || [];
    log.history.push(arguments);
    if (this.console) {
        var args = arguments,
            newarr;
        args.callee = args.callee.caller;
        newarr = [].slice.call(args);
        if (typeof console.log === 'object') log.apply.call(console.log, console, newarr);
        else console.log.apply(console, newarr);
    }
};

// make it safe to use console.log always
(function(a) {
    function b() {}
    for (var c = "assert,count,debug,dir,dirxml,error,exception,group,groupCollapsed,groupEnd,info,log,markTimeline,profile,profileEnd,time,timeEnd,trace,warn".split(","), d; !! (d = c.pop());) {
        a[d] = a[d] || b;
    }
})(function() {
    try {
        console.log();
        return window.console;
    } catch(a) {
        return (window.console = {});
    }
} ());
Сэм Джонс
источник
1

Я использую подход Уолтера сверху (см .: https://stackoverflow.com/a/14246240/3076102 )

Я смешиваю в решение, которое я нашел здесь https://stackoverflow.com/a/7967670 чтобы правильно показывать объекты.

Это означает, что функция ловушки становится:

function trap(){
    if(debugging){
        // create an Array from the arguments Object           
        var args = Array.prototype.slice.call(arguments);
        // console.raw captures the raw args, without converting toString
        console.raw.push(args);
        var index;
        for (index = 0; index < args.length; ++index) {
            //fix for objects
            if(typeof args[index] === 'object'){ 
                args[index] = JSON.stringify(args[index],null,'\t').replace(/\n/g,'<br>').replace(/\t/g,'&nbsp;&nbsp;&nbsp;');
            }
        }
        var message = args.join(' ');
        console.messages.push(message);
        // instead of a fallback function we use the next few lines to output logs
        // at the bottom of the page with jQuery
        if($){
            if($('#_console_log').length == 0) $('body').append($('<div />').attr('id', '_console_log'));
            $('#_console_log').append(message).append($('<br />'));
        }
    }
} 

Я надеюсь, что это полезно :-)

Раймонд Эльферинк
источник
0

Это работает в IE8. Откройте Инструменты разработчика IE8, нажав F12.

>>console.log('test')
LOG: test
Константин Таркус
источник
6
В моем случае это "неопределенный"
акме
6
Как указал Мистер Лаки: «console.log доступен только после того, как вы открыли Инструменты разработчика (F12 для переключения его открытия и закрытия)».
Глушитель
0

Мне нравится этот метод (с использованием jquery's doc ready) ... он позволяет вам использовать консоль даже в ie ... единственное преимущество в том, что вам нужно перезагрузить страницу, если вы открываете инструменты ie после загрузки страницы ...

это может быть проще, если учесть все функции, но я использую только журнал, так что это то, что я делаю.

//one last double check against stray console.logs
$(document).ready(function (){
    try {
        console.log('testing for console in itcutils');
    } catch (e) {
        window.console = new (function (){ this.log = function (val) {
            //do nothing
        }})();
    }
});
user3560902
источник
0

Вот версия, которая будет входить в консоль, когда инструменты разработчика открыты, а не когда они закрыты.

(function(window) {

   var console = {};
   console.log = function() {
      if (window.console && (typeof window.console.log === 'function' || typeof window.console.log === 'object')) {
         window.console.log.apply(window, arguments);
      }
   }

   // Rest of your application here

})(window)
Джордж Райт
источник
Хорошо, что он ограничен по объему, может поддерживать случай, когда IE8 DevTools открыт в середине выполнения кода, но он не работает в IE8, console.log является объектом, поэтому у него нет applyметода.
Ниши
0

Создайте свою собственную консоль в html .... ;-) Это может быть замечено, но вы можете начать с:

if (typeof console == "undefined" || typeof console.log === "undefined") {
    var oDiv=document.createElement("div");
    var attr = document.createAttribute('id'); attr.value = 'html-console';
    oDiv.setAttributeNode(attr);


    var style= document.createAttribute('style');
    style.value = "overflow: auto; color: red; position: fixed; bottom:0; background-color: black; height: 200px; width: 100%; filter: alpha(opacity=80);";
    oDiv.setAttributeNode(style);

    var t = document.createElement("h3");
    var tcontent = document.createTextNode('console');
    t.appendChild(tcontent);
    oDiv.appendChild(t);

    document.body.appendChild(oDiv);
    var htmlConsole = document.getElementById('html-console');
    window.console = {
        log: function(message) {
            var p = document.createElement("p");
            var content = document.createTextNode(message.toString());
            p.appendChild(content);
            htmlConsole.appendChild(p);
        }
    };
}
Александр Ассуад
источник