"консоль" - це невизначена помилка для Internet Explorer


375

Я використовую Firebug і маю такі заяви, як:

console.log("...");

на моїй сторінці. У IE8 (можливо, і більш ранніх версіях) я отримую помилки сценарію, кажучи, що "консоль" не визначена. Я спробував поставити це вгорі сторінки:

<script type="text/javascript">
    if (!console) console = {log: function() {}};
</script>

все-таки я отримую помилки. Будь-який спосіб позбутися від помилок?


4
Використовуйте typeofу своєму, якщо це дозволить уникнути невизначених помилок: if(typeof console === "undefined") { var console = { log: function (logMsg) { } }; }
Flak DiNenno

21
console.log () працює лише тоді, коли відкритий інструмент розробки IE (так IE є шаленим). дивіться stackoverflow.com/questions/7742781/…
Adrien Be

1
Найкраща відповідь на це питання - stackoverflow.com/a/16916941/2274855
Vinícius Moraes


1
Посилання @Aprillion розірвано, використовуйте замість цього: github.com/h5bp/html5-boilerplate/blob/master/src/js/plugins.js
Альфред Без

Відповіді:


378

Спробуйте

if (!window.console) console = ...

Не визначена змінна не може бути спрямована безпосередньо. Однак усі глобальні змінні є атрибутами з однаковим іменем глобального контексту ( windowу разі браузерів), і доступ до невизначеного атрибута є прекрасним.

Або скористайтеся, if (typeof console === 'undefined') console = ...якщо ви хочете уникнути магічної змінної window, дивіться відповідь @Tim Down .


160
Просто, щоб зрозуміти, хто користується цим, розмістіть <script type="text/javascript"> if (!window.console) console = {log: function() {}}; </script>у верхній частині сторінки! Дякую Кенні
windowsgm

11
Про щоvar console = console || { log: function() {} };
devlord

9
@lorddev Щоб скористатися цією стенограмою, вам потрібно включити window:var console = window.console || { log: function() {} };
jlengstorf

64
Чорт ... ви створюєте приємний веб-сайт, розробляючи його для улюбленого браузера. Зрештою, ви витрачаєте 4-5 годин на сумісність з усіма іншими сучасними браузерами, а потім витрачаєте 4-5 днів, роблячи сумісність з IE.
Ізраїль

6
Проблема з цією відповіддю полягає в тому, що якщо ви використовуєте інше ім'я, наприклад, налагодження, попереджайте, рахуйте в браузері, що відсутність консолі викине виняток, побачите кращий спосіб зробити це stackoverflow.com/a/16916941/2274855
Vinícius Moraes

319

Вставте наступне у верхній частині свого JavaScript (перш ніж використовувати консоль):

/**
 * Protect window.console method calls, e.g. console is not defined on IE
 * unless dev tools are open, and IE doesn't define console.debug
 * 
 * Chrome 41.0.2272.118: debug,error,info,log,warn,dir,dirxml,table,trace,assert,count,markTimeline,profile,profileEnd,time,timeEnd,timeStamp,timeline,timelineEnd,group,groupCollapsed,groupEnd,clear
 * Firefox 37.0.1: log,info,warn,error,exception,debug,table,trace,dir,group,groupCollapsed,groupEnd,time,timeEnd,profile,profileEnd,assert,count
 * Internet Explorer 11: select,log,info,warn,error,debug,assert,time,timeEnd,timeStamp,group,groupCollapsed,groupEnd,trace,clear,dir,dirxml,count,countReset,cd
 * Safari 6.2.4: debug,error,log,info,warn,clear,dir,dirxml,table,trace,assert,count,profile,profileEnd,time,timeEnd,timeStamp,group,groupCollapsed,groupEnd
 * Opera 28.0.1750.48: debug,error,info,log,warn,dir,dirxml,table,trace,assert,count,markTimeline,profile,profileEnd,time,timeEnd,timeStamp,timeline,timelineEnd,group,groupCollapsed,groupEnd,clear
 */
(function() {
  // Union of Chrome, Firefox, IE, Opera, and Safari console methods
  var methods = ["assert", "cd", "clear", "count", "countReset",
    "debug", "dir", "dirxml", "error", "exception", "group", "groupCollapsed",
    "groupEnd", "info", "log", "markTimeline", "profile", "profileEnd",
    "select", "table", "time", "timeEnd", "timeStamp", "timeline",
    "timelineEnd", "trace", "warn"];
  var length = methods.length;
  var console = (window.console = window.console || {});
  var method;
  var noop = function() {};
  while (length--) {
    method = methods[length];
    // define undefined methods as noops to prevent errors
    if (!console[method])
      console[method] = noop;
  }
})();

Обгортка функції закриття полягає в обміні змінних, щоб не визначати жодних змінних. Це захищає як невизначені, так consoleі невизначені console.debug(та інші відсутні методи).

EDIT: Я помітив, що HTML5 Boilerplate використовує подібний код у своєму файлі js / plugins.js, якщо ви шукаєте рішення, яке (ймовірно) буде постійно оновлюватися.


14
Чому ця відповідь має так мало відгуків? Це найповніший один із розміщених тут.
mavilein

Через дату. Абсолютно згодні з правильними робочими рішеннями. Я думаю, що цю тему потрібно модерувати. Вибачте за погану англійську.
woto

Цілком завершено, за винятком того, що він не намагатиметься перенаправляти журнал на функцію журналу (якщо є), щоб усі журнали були втрачені
Крістоф Руссі

5
Коли це відбулося б саме? Цей код повинен визначати лише ті елементи, які ще не визначені.
Пітер Ценг

4
Я думаю, що так чи інакше - (функція () {...} ()) або (функція () {...}) () - працює насправді
Пітер Ценг

73

Ще одна альтернатива - typeofоператор:

if (typeof console == "undefined") {
    this.console = {log: function() {}};
}

Ще одна альтернатива - використання бібліотеки журналів, наприклад мого власного log4javascript .


Однак було б непогано змінити незадеклароване призначення на належну декларацію.
кенгакс

1
Ви маєте на увазі використання var? Це лише заплутало б тут речі. Або ти маєш на увазі присвоєння, window.consoleа не console?
Тім Даун

Використання var. Чому б це плутати тут речі?
кенгакс

2
Що заплутане обговорення. +1 до початкової відповіді. Якби я міг дати +2, я би за надання посилання на ваш власний log4javascript. Дякую ОП!
Джей Тейлор

8
@yckart: Ні. typeofгарантовано повертає рядок і "undefined"є рядком. Коли два операнди однотипні ==і ===задані для виконання точно однакових кроків. Використання typeof x == "undefined"- це надійний спосіб перевірити, чи xне визначено його в будь-якій області та будь-якому середовищі, сумісному з ECMAScript 3.
Tim Down

47

Для більш надійного рішення використовуйте цей фрагмент коду (узятий із вихідного коду Twitter):

// 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;
        }
    }
}());

13

У своїх сценаріях я або використовую скорочення:

window.console && console.log(...) // only log if the function exists

або, якщо неможливо чи можливо відредагувати кожен рядок console.log, я створюю підроблену консоль:

// check to see if console exists. If not, create an empty object for it,
// then create and empty logging function which does nothing. 
//
// REMEMBER: put this before any other console.log calls
!window.console && (window.console = {} && window.console.log = function () {});

2
Синтаксична помилка. Чому б не простоif(!console) {console = {} ; console.log = function(){};}
Meekohi

1
Або не просто!window.console && (window.console = { log: function () { } });
Максим Ві.

10

Ви можете використовувати, console.log()якщо у вас Developer Toolsвідкритий IE8, а також ви можете використовувати Consoleтекстове поле на вкладці сценарію.


7
Це не добре, якщо ви забудете зрушити код консолі. Помилка IE8 не дозволить вашому коду JS працювати
yunzen

7
if (typeof console == "undefined") {
  this.console = {
    log: function() {},
    info: function() {},
    error: function() {},
    warn: function() {}
  };
}

1
застереження: це слід визначити на глобальному рівні, де thisйдеться window.
Sgnl

7

На основі двох попередніх відповідей

та документації на

Ось найкраща реалізація для вирішення проблеми, тобто якщо існує консоль.log, який фактично існує, він заповнює прогалини для неіснуючих методів через console.log.

Наприклад, для IE6 / 7 ви можете замінити ведення журналу на попередження (нерозумно, але працює), а потім включити монстр нижче (я назвав його console.js): [Не соромтесь видаляти коментарі, як вважаєте за потрібне, я залишив їх для довідки, мінімізатор може вирішити їх]:

<!--[if lte IE 7]>
<SCRIPT LANGUAGE="javascript">
    (window.console = window.console || {}).log = function() { return window.alert.apply(window, arguments); };
</SCRIPT>
<![endif]-->
<script type="text/javascript" src="console.js"></script>

і console.js:

    /**
     * Protect window.console method calls, e.g. console is not defined on IE
     * unless dev tools are open, and IE doesn't define console.debug
     */
    (function() {
        var console = (window.console = window.console || {});
        var noop = function () {};
        var log = console.log || noop;
        var start = function(name) { return function(param) { log("Start " + name + ": " + param); } };
        var end = function(name) { return function(param) { log("End " + name + ": " + param); } };

        var methods = {
            // Internet Explorer (IE 10): http://msdn.microsoft.com/en-us/library/ie/hh772169(v=vs.85).aspx#methods
            // assert(test, message, optionalParams), clear(), count(countTitle), debug(message, optionalParams), dir(value, optionalParams), dirxml(value), error(message, optionalParams), group(groupTitle), groupCollapsed(groupTitle), groupEnd([groupTitle]), info(message, optionalParams), log(message, optionalParams), msIsIndependentlyComposed(oElementNode), profile(reportName), profileEnd(), time(timerName), timeEnd(timerName), trace(), warn(message, optionalParams)
            // "assert", "clear", "count", "debug", "dir", "dirxml", "error", "group", "groupCollapsed", "groupEnd", "info", "log", "msIsIndependentlyComposed", "profile", "profileEnd", "time", "timeEnd", "trace", "warn"

            // Safari (2012. 07. 23.): https://developer.apple.com/library/safari/#documentation/AppleApplications/Conceptual/Safari_Developer_Guide/DebuggingYourWebsite/DebuggingYourWebsite.html#//apple_ref/doc/uid/TP40007874-CH8-SW20
            // assert(expression, message-object), count([title]), debug([message-object]), dir(object), dirxml(node), error(message-object), group(message-object), groupEnd(), info(message-object), log(message-object), profile([title]), profileEnd([title]), time(name), markTimeline("string"), trace(), warn(message-object)
            // "assert", "count", "debug", "dir", "dirxml", "error", "group", "groupEnd", "info", "log", "profile", "profileEnd", "time", "markTimeline", "trace", "warn"

            // Firefox (2013. 05. 20.): https://developer.mozilla.org/en-US/docs/Web/API/console
            // debug(obj1 [, obj2, ..., objN]), debug(msg [, subst1, ..., substN]), dir(object), error(obj1 [, obj2, ..., objN]), error(msg [, subst1, ..., substN]), group(), groupCollapsed(), groupEnd(), info(obj1 [, obj2, ..., objN]), info(msg [, subst1, ..., substN]), log(obj1 [, obj2, ..., objN]), log(msg [, subst1, ..., substN]), time(timerName), timeEnd(timerName), trace(), warn(obj1 [, obj2, ..., objN]), warn(msg [, subst1, ..., substN])
            // "debug", "dir", "error", "group", "groupCollapsed", "groupEnd", "info", "log", "time", "timeEnd", "trace", "warn"

            // Chrome (2013. 01. 25.): https://developers.google.com/chrome-developer-tools/docs/console-api
            // assert(expression, object), clear(), count(label), debug(object [, object, ...]), dir(object), dirxml(object), error(object [, object, ...]), group(object[, object, ...]), groupCollapsed(object[, object, ...]), groupEnd(), info(object [, object, ...]), log(object [, object, ...]), profile([label]), profileEnd(), time(label), timeEnd(label), timeStamp([label]), trace(), warn(object [, object, ...])
            // "assert", "clear", "count", "debug", "dir", "dirxml", "error", "group", "groupCollapsed", "groupEnd", "info", "log", "profile", "profileEnd", "time", "timeEnd", "timeStamp", "trace", "warn"
            // Chrome (2012. 10. 04.): https://developers.google.com/web-toolkit/speedtracer/logging-api
            // markTimeline(String)
            // "markTimeline"

            assert: noop, clear: noop, trace: noop, count: noop, timeStamp: noop, msIsIndependentlyComposed: noop,
            debug: log, info: log, log: log, warn: log, error: log,
            dir: log, dirxml: log, markTimeline: log,
            group: start('group'), groupCollapsed: start('groupCollapsed'), groupEnd: end('group'),
            profile: start('profile'), profileEnd: end('profile'),
            time: start('time'), timeEnd: end('time')
        };

        for (var method in methods) {
            if ( methods.hasOwnProperty(method) && !(method in console) ) { // define undefined methods as best-effort methods
                console[method] = methods[method];
            }
        }
    })();

Я не впевнений, чи потрібно нам methods.hasOwnProperty(method) && у циклі for.
TWiStErRob

Я впевнений, що вам це потрібно.
ErikE

Зробив швидкий тест на консолі Chrome: > x = { a: 1, b: 2}-> Object {a: 1, b: 2}та for(var f in x) {console.log(f + " " + x[f]);} 'end'-> a 1 b 2 "end". Отже, створений анонімний об'єкт не має ніякого додаткового властивості, а methodsпросто створюється перед forциклом. Чи можна зламати вище?
TWiStErRob

3
Так. var x = { a: 1, b: 2}; Object.prototype.surprise = 'I\'m in yer objectz'; for (var f in x) {console.log(f, x[f]);}Ви ніколи не знаєте, що бібліотека зробила з об'єктами в ланцюжку спадкування об'єкта, з яким ви працюєте. Таким чином, рекомендація щодо використання інструментів якості коду JavaScript, таких як jshint та jslint, використовувати hasOwnProperty.
ErikE

6

У IE9, якщо консоль не відкрита, цей код:

alert(typeof console);

покаже "об'єкт", але цей код

alert(typeof console.log);

викине виняток TypeError, але не поверне невизначене значення;

Отже, гарантована версія коду буде схожа на цю:

try {
    if (window.console && window.console.log) {
        my_console_log = window.console.log;
    }
} catch (e) {
    my_console_log = function() {};
}

6

У коді я використовую лише console.log. Тому я включаю дуже короткий 2 лайнера

var console = console || {};
console.log = console.log || function(){};

1
Як працює ... Я не бачу жодного рядка console.log, надрукованого в браузері IE, я протестував з двома різними системами, де в 1 - console.log працює, а в 2 - не. Я спробував в обох, але не зміг побачити жодного журналу в обох системах.
кіран

2

Помітили, що OP використовує Firebug з IE, тому припускайте, що це Firebug Lite . Це прикольна ситуація, коли консоль визначається в IE при відкритті вікна налагодження, але що відбувається, коли Firebug вже працює? Не впевнений, але, можливо, метод "firebugx.js" може бути хорошим способом перевірити в цій ситуації:

джерело:

https://code.google.com/p/fbug/source/browse/branches/firebug1.2/lite/firebugx.js?r=187

    if (!window.console || !console.firebug) {
        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() {}
    }

(оновлені посилання 12/2014)



1

Для налагодження в IE перевірте цей log4javascript


Це чудово, тим більше, що моя консоль IE8 нічого не дає.
Фірш - LetsWP.io

1
@Firsh Дякуємо за ваші коментарі.
Правен

1
Я шукав коментар до іншого питання, яке сказав "безсоромне саморекламування", або я не знаю - подібного - хтось, хто сказав, що створив цього наука, це ти? Я вже закрив цю вкладку. У будь-якому випадку це дійсно чудовий інструмент і дуже корисний для мого проекту.
Фірш - LetsWP.io

1
@Firsh Я не створив цей сценарій, я такий, як ви, користувався інструментом.
Правен

1

Для підтримки IE8 або консолі, обмеженої console.log (без налагодження, трасування, ...), ви можете зробити наступне:

  • Якщо консоль АБО console.log undefined: Створіть фіктивні функції для функцій консолі (слід, налагодження, журнал, ...)

    window.console = { debug : function() {}, ...};

  • В іншому випадку, якщо визначено console.log (IE8) І console.debug (будь-який інший) не визначено: перенаправити всі функції реєстрації на console.log, це дозволяє зберігати ці журнали!

    window.console = { debug : window.console.log, ...};

Не впевнений у підтримці затвердження у різних версіях IE, але будь-які пропозиції вітаються. Також розмістив цю відповідь тут: Як я можу використовувати консольний журнал в Internet Explorer?



1

Заглушка консолі в TypeScript:

if (!window.console) {
console = {
    assert: () => { },
    clear: () => { },
    count: () => { },
    debug: () => { },
    dir: () => { },
    dirxml: () => { },
    error: () => { },
    group: () => { },
    groupCollapsed: () => { },
    groupEnd: () => { },
    info: () => { },
    log: () => { },
    msIsIndependentlyComposed: (e: Element) => false,
    profile: () => { },
    profileEnd: () => { },
    select: () => { },
    time: () => { },
    timeEnd: () => { },
    trace: () => { },
    warn: () => { },
    }
};

0

Ви можете скористатися наведеними нижче способами, щоб забезпечити додатковий рівень страхування, що маєте покриті всі бази. Використання typeofспочатку дозволить уникнути undefinedпомилок. Використання ===також забезпечить, що ім'я типу є насправді рядком "undefined". Нарешті, ви хочете додати параметр до підпису функції (я вибрав logMsgдовільно), щоб забезпечити узгодженість, оскільки ви передаєте все те, що ви хочете, надрукували на консолі функції журналу. Це також забезпечує точність інтелігенції та дозволяє уникнути будь-яких попереджень / помилок у вашому IDE, що знає JS.

if(!window.console || typeof console === "undefined") {
  var console = { log: function (logMsg) { } };
}


0

Зустрічалася аналогічна проблема запуску console.log у дочірніх вікнах IE9, створених функцією window.open.

Здається, що в цьому випадку консоль визначається лише у батьківському вікні та не визначена у дочірніх вікнах, поки ви не оновите їх. Те саме стосується дітей дитячих вікон.

Я вирішую цю проблему, вкладаючи наступну функцію (увімкнути фрагмент модуля)

getConsole: function()
    {
        if (typeof console !== 'undefined') return console;

        var searchDepthMax = 5,
            searchDepth = 0,
            context = window.opener;

        while (!!context && searchDepth < searchDepthMax)
        {
            if (typeof context.console !== 'undefined') return context.console;

            context = context.opener;
            searchDepth++;
        }

        return null;
    },
    log: function(message){
        var _console = this.getConsole();
        if (!!_console) _console.log(message);
    }

-2

У мене виникло стільки проблем з цією справою (важко налагодити помилку, оскільки якщо ви відкриєте консоль розробника, помилка більше не трапляється!) Я вирішив зробити код надмірного вбивства, щоб більше ніколи не турбуватися з цим:

if (typeof window.console === "undefined")
    window.console = {};

if (typeof window.console.debug === "undefined")
    window.console.debug= function() {};

if (typeof window.console.log === "undefined")
    window.console.log= function() {};

if (typeof window.console.error === "undefined")
    window.console.error= function() {alert("error");};

if (typeof window.console.time === "undefined")
    window.console.time= function() {};

if (typeof window.console.trace === "undefined")
    window.console.trace= function() {};

if (typeof window.console.info === "undefined")
    window.console.info= function() {};

if (typeof window.console.timeEnd === "undefined")
    window.console.timeEnd= function() {};

if (typeof window.console.group === "undefined")
    window.console.group= function() {};

if (typeof window.console.groupEnd === "undefined")
    window.console.groupEnd= function() {};

if (typeof window.console.groupCollapsed === "undefined")
    window.console.groupCollapsed= function() {};

if (typeof window.console.dir === "undefined")
    window.console.dir= function() {};

if (typeof window.console.warn === "undefined")
    window.console.warn= function() {};

Я особисто використовую лише console.log та console.error, але цей код обробляє всі інші функції, як показано в Мережі розробників Mozzila: https://developer.mozilla.org/en-US/docs/Web/API/console . Просто поставте цей код у верхній частині сторінки, і з цим ви назавжди закінчите.


-11

Ви можете використовувати console.log (...) безпосередньо в Firefox, але не в IE. У IE ви повинні використовувати window.console.


11
console.log та window.console.log посилаються на ту саму функцію в будь-якому браузері, яка навіть віддалено відповідає ECMAscript. Останньою практикою є використання останньої, щоб уникнути випадкової затінення локальної змінної об'єкта глобальної консолі, але це не має нічого спільного з вибором браузера. console.log прекрасно працює в IE8, а AFAIK взагалі не має можливості реєстрації в IE6 / 7.
Тгр
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.