Чому JavaScript працює лише після відкриття інструментів для розробників в IE один раз?


638

IE9 Bug - JavaScript працює лише після відкриття інструментів для розробників один раз.

Наш сайт пропонує безкоштовне завантаження файлів у форматі PDF для користувачів, і він має просту функцію "ввести пароль для завантаження". Однак це зовсім не працює в Internet Explorer.

Ви можете переконатися в цьому прикладі .

Пропуск для завантаження - "makeuseof". У будь-якому іншому браузері це працює чудово. В IE обидві кнопки нічого не роблять.

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

Ми спробували режим сумісності, і таке, нічого не має значення.

Як зробити цю роботу в Internet Explorer?


3
використовувати перехресну браузерну обгортку: github.com/MichaelZelensky/log.js
Михайло Зеленський

1
Хорошою альтернативою, якщо у вас є крок складання, є використання чогось подібного gulp-strip-debug. Це видаляє всі console.*методи, чудові для нарощування виробництва або тестування в IE.
knownasilya

15
Для майбутніх гуглерів: у мене були ті ж симптоми, але в IE11. Ну, виявилося, що відповідь стосувалася не consoleмого, а мого використання кутових та кешування запитів отримати. Дивіться відповіді тут і тут для отримання додаткової інформації.
Крістофер Летте

@ChristofferLette Так, у мене є те саме питання, будь ласка, перевірте stackoverflow.com/questions/31428126/… код працює належним чином, коли інструменти для розробників відкриті ..
Pranav Bilurkar

5
Найприємніше у таких проблемах? Налагодити їх майже неможливо, оскільки він починає працювати, як тільки ви відкриєте консоль розробника.
jlewkovich

Відповіді:


815

Здається, що у вашому JavaScript може бути якийсь код налагодження.

Опис, який ви описуєте, типовий для коду, який містить console.log()або будь-який інший consoleфункціонал.

consoleОб'єкт активується тільки тоді , коли Dev панель відкрита. До цього виклик об’єкта консолі призведе до того, що він повідомляється як undefined. Після відкриття панелі інструментів консоль існуватиме (навіть якщо панель інструментів згодом буде закрита), тож виклики консолі працюватимуть потім.

Є кілька рішень для цього:

Найбільш очевидний - пройти свій код, видаливши посилання на console. Ви не повинні залишати подібні речі у виробничому коді.

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


8
Чи є якісь обхідні шляхи для залишення коду налагодження? IE - єдиний браузер із такою непристойною поведінкою ...
Meekohi

94
if(!console) {console={}; console.log = function(){};}
Meekohi

79
@Meekohi if(!console)призведе до тієї ж помилки - це слід прочитатиif(!window.console)
mindplay.dk

9
тож ... IE не повинен реалізовувати функцію, яку кожен новий js-розробник використовує весь час, щоб не дратувати декількох розробників, які використовували сценарій, щоб виправити те, що повинно було працювати в першу чергу ... але це несправедливо стукати IE за це? Ви дуже щедра людина Спадлі !!! :)
Джордан Девіс

7
Все ще трапляється з IE11
Michael

162

HTML5 Boilerplate має гарний попередньо зроблений код для вирішення проблем із консоллю:

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

Як @ плюс - зазначив у коментарях, остання версія доступна на їхній сторінці GitHub


8
Посилання в коментарі @plus більше не діє. Код було висунуто в srcпідрозділ: github.com/h5bp/html5-boilerplate/blob/master/src/js/plugins.js
Christoffer Lette

153

Ось ще одна можлива причина, окрім console.logпроблеми (принаймні в IE11):

Якщо консоль не відкрита, IE робить досить агресивне кешування, тому переконайтесь, що для будь-яких $.ajaxвикликів чи XMLHttpRequestвикликів кешування встановлено на хибне.

Наприклад:

$.ajax({cache: false, ...})

Коли консоль розробника відкрита, кешування є менш агресивним. Здається, це помилка (чи, можливо, функція?)


9
Це мене просто врятувало;) Спасибі! Я б сказав, що це помилка, оскільки у вас повинні бути однакові умови для тестування та налагодження веб-сайту з відкритою та закритою консоллю.
Чноч

Працювали для мене. В зокрема: stackoverflow.com/questions/13391563 / ...
user1062589

2
це повинно бути вищим, оскільки я думаю, що це реальна відповідь ... прийнята відповідь щодо console.log в якійсь версії IE призведе до помилки, не викликаної описаною тут поведінкою.
Мігс

63

Це вирішило мою проблему після того, як я змінив її. Я додав наступне на своїй html-сторінці для вирішення проблеми IE9:

<script type="text/javascript">
    // IE9 fix
    if(!window.console) {
        var console = {
            log : function(){},
            warn : function(){},
            error : function(){},
            time : function(){},
            timeEnd : function(){}
        }
    }
</script>

1
Це рішення не працює на IE 11 у Windows 7 64-розрядному.
Вікрам

1
Це вирішило мою проблему на IE 11 на Windows 7 64-розрядний.
zonyang

29

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

Коли ввімкнено Інструменти для розробників, IE насправді не використовує кеш HTTP (принаймні за замовчуванням в IE 11), як це робиться в звичайному режимі.

Це означає, що якщо на вашому веб-сайті або на сторінці є проблема кешування (якщо він кеширується більше, ніж слід, наприклад, це було в моєму випадку), ви не побачите цю проблему в режимі F12. Тож якщо javascript виконує кілька кешованих запитів AJAX, вони можуть не працювати, як очікувалося, у звичайному режимі, і працюватимуть нормально у режимі F12.


1
Див stackoverflow.com/questions/3984961 / ... про те , як відключити запит кешування xmlHttpReq.
Майкл Росс

1
Солодке. Це напрочуд спрацювало. Я думаю, що $ http сервіс Angular не кешує бюст, як я вважав, що це буде.

17

Я думаю, це може допомогти, додавши це перед будь-яким тегом javascript:

try{
  console
}catch(e){
   console={}; console.log = function(){};
}

11
try catchвиявити наявність змінної - це погана ідея. Мало того, що це повільно, але якщо у вашому блоці спробу є кілька заяв, ви можете отримати виняток з іншої причини. Не використовуйте це, як мінімум,if (typeof console == 'undefined')
Хуан Мендес

8

Якщо ви використовуєте AngularJS версії 1.X, ви можете скористатися послугою журналу $ замість безпосередньо console.log.

Простий сервіс для ведення журналу. Реалізація за замовчуванням безпечно записує повідомлення в консоль браузера (якщо він присутній).

https://docs.angularjs.org/api/ng/service/$log

Тож якщо у вас є щось подібне

angular.module('logExample', [])
  .controller('LogController', ['$scope', function($scope) {
    console.log('Hello World!');
 }]);

ви можете замінити його

angular.module('logExample', [])
  .controller('LogController', ['$scope', '$log', function($scope, $log) {
    $log.log('Hello World!');
 }]);

Angular 2+ не має жодної вбудованої служби журналу .


це допомогло мені, дякую - для всіх, хто використовує машинопис, це "ILogService" у кутових визначеннях
DannykPowell

IIRC, що використовує $ log, примикає розташування оператора журналу, на відміну від використання console.log. Не такий великий із мого досвіду під час розвитку.
JesseDahl

5

Якщо ви використовуєте angularі тобто 9, 10або edgeвикористовуєте:

myModule.config(['$httpProvider', function($httpProvider) {
    //initialize get if not there
    if (!$httpProvider.defaults.headers.get) {
        $httpProvider.defaults.headers.get = {};    
    }    

    // Answer edited to include suggestions from comments
    // because previous version of code introduced browser-related errors

    //disable IE ajax request caching
    $httpProvider.defaults.headers.get['If-Modified-Since'] = 'Mon, 26 Jul 1997 05:00:00 GMT';
    // extra
    $httpProvider.defaults.headers.get['Cache-Control'] = 'no-cache';
    $httpProvider.defaults.headers.get['Pragma'] = 'no-cache';
}]);

Повністю відключити cache.


4

Це сталося в IE 11 для мене. І я викликав функцію jquery .load. Тому я зробив це за старим способом і вніс щось у URL, щоб відключити кешування.

$("#divToReplaceHtml").load('@Url.Action("Action", "Controller")/' + @Model.ID + "?nocache=" + new Date().getTime());

2

У мене з'явилася ще одна альтернатива для рішень, пропонованих рунеками і тодотресде, що також дозволяє уникнути підводних каменів, обговорених у коментарях до відповіді Спадлі :

        try {
            console.log(message);
        } catch (e) {
        }

Це трохи вибагливо, але, з іншого боку, він стислий і охоплює всі способи ведення журналу, що містяться у відповіді рунеків , і це величезна перевага в тому, що ви можете відкрити вікно консолі IE у будь-який час і журнали надходять у них.


0

Ми зіткнулися з цією проблемою в IE 11 в Windows 7 і Windows 10. Ми виявили, в чому саме полягає проблема, включивши можливості налагодження IE (IE> Internet Options> Додаткова вкладка> Перегляд> Зніміть позначку Відключити налагодження сценарію (Internet Explorer) ). Цю функцію зазвичай перевіряють у нашому середовищі адміністратори домену.

Проблема була в тому, що ми використовували console.debug(...)метод в коді JavaScript. Припущення, зроблене розробником (мною), - це те, що я не хотів нічого написаного, якщо консоль клієнтських інструментів розробника не була явно відкритою. Хоча Chrome і Firefox, здавалося, погоджуються з цією стратегією, IE 11 не сподобався ні на один біт. Змінивши всі console.debug(...)заяви на console.log(...)заяви, ми змогли продовжувати записувати додаткову інформацію на консолі клієнта та переглядати її, коли вона була відкрита, але в іншому випадку зберігати її прихованою від типового користувача.


0

Я розміщую резолюцію і виправляю свою проблему. Схоже, запит AJAX, який я помістив всередині свого JavaScript, не обробляв, оскільки на моїй сторінці виникли проблеми з кешем. якщо на вашому веб-сайті або на сторінці є проблема кешування, ви не побачите цієї проблеми в режимі розробників / F12. мій кешований JavaScript AJAX вимагає, щоб він не працював так, як очікувалося, і призведе до порушення функції виконання, у якої F12 взагалі не має проблем. Тому просто додали новий параметр, щоб зробити кеш помилковим.

$.ajax({
  cache: false,
});

Схоже, IE спеціально потребує цього, щоб це було помилковим, щоб активність AJAX та JavaScript працювала добре.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.