Dlaczego JavaScript działa tylko po jednorazowym otwarciu narzędzi programistycznych w IE?

638

Błąd IE9 - JavaScript działa tylko po jednorazowym otwarciu narzędzi programistycznych.

Nasza strona oferuje użytkownikom bezpłatne pobieranie plików PDF i ma prostą funkcję „wprowadź hasło, aby pobrać”. Jednak w ogóle nie działa w przeglądarce Internet Explorer.

Możesz zobaczyć sam w tym przykładzie .

Karta pobierania to „makeuseof”. W każdej innej przeglądarce działa dobrze. W IE oba przyciski nic nie robią.

Najciekawsze, co znalazłem, to to, że jeśli otworzysz i zamkniesz pasek narzędzi programisty za pomocą F12, wszystko nagle zacznie działać.

Wypróbowaliśmy tryb kompatybilności i nic nie robi różnicy.

Jak sprawić, by działało w Internet Explorerze?

James Bruce
źródło
3
użyj opakowania przeglądarki: github.com/MichaelZelensky/log.js
Michael
1
Dobrą alternatywą, jeśli masz krok kompilacji, jest użycie czegoś takiego gulp-strip-debug. Usuwa wszystkie console.*metody, idealne do kompilacji produkcyjnych lub testowania w IE.
knownasilya
15
Dla przyszłych pracowników Google: miałem te same objawy, ale w IE11. Okazało się, że odpowiedź nie była związana console, ale z moim wykorzystaniem kątowego i buforowania żądań get. Zobacz odpowiedzi tutaj i tutaj, aby uzyskać więcej.
Christoffer Lette,
@ChristofferLette Tak, mam ten sam problem, sprawdź kod stackoverflow.com/questions/31428126/... działa poprawnie, gdy narzędzia programistyczne są otwarte ..
Pranav Bilurkar
5
Najbardziej denerwująca rzecz w takich problemach? Debugowanie jest prawie niemożliwe, ponieważ zaczyna działać natychmiast po otwarciu konsoli programisty.
jlewkovich

Odpowiedzi:

815

Wygląda na to, że możesz mieć jakiś kod debugujący w swoim javascript.

Opisywane przez Ciebie doświadczenie jest typowe dla kodu, który zawiera console.log()lub jakąkolwiek inną consolefunkcjonalność.

consoleObiekt jest aktywna tylko wtedy, gdy Dev Toolbar jest otwarty. Wcześniej wywołanie obiektu konsoli spowoduje zgłoszenie go jako undefined. Po otwarciu paska narzędzi konsola będzie istnieć (nawet jeśli pasek narzędzi zostanie następnie zamknięty), więc wywołania konsoli będą wtedy działać.

Istnieje kilka rozwiązań tego:

Najbardziej oczywistym jest przejście przez kod i usunięcie odniesień do console. I tak nie powinieneś zostawiać takich rzeczy w kodzie produkcyjnym.

Jeśli chcesz zachować odwołania do konsoli, możesz zawinąć je w if()instrukcję lub w inny warunek, który sprawdza, czy obiekt konsoli istnieje przed próbą jego wywołania.

Spudley
źródło
8
Czy są jakieś obejścia dla pozostawienia kodu debugującego? IE jest jedyną przeglądarką z tym
szalonym
94
if(!console) {console={}; console.log = function(){};}
Meekohi
79
@ Meekohi if(!console)spowoduje ten sam błąd - powinien przeczytaćif(!window.console)
mindplay.dk
9
więc ... IE nie powinien implementować funkcji, z której korzysta każdy nowy program js, aby uniknąć denerwowania kilku deweloperów, którzy używali skryptu do naprawy rzeczy, która powinna była działać przede wszystkim ... ale to niesprawiedliwe zapukać do tego IE? Jesteś bardzo hojną osobą Spudley !!! :)
Jordan Davis,
7
Nadal dzieje się z IE11
Michael
162

HTML5 Boilerplate ma ładny, gotowy kod do rozwiązywania problemów z konsolą:

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

Jak wskazano w komentarzach @ plus, najnowsza wersja jest dostępna na ich stronie GitHub

Tallmaris
źródło
8
Link w komentarzu @plus jest już nieaktualny. Kod został zepchnięty do srcpodkatalogu: github.com/h5bp/html5-boilerplate/blob/master/src/js/plugins.js
Christoffer Lette
153

Oto inny możliwy powód oprócz console.logproblemu (przynajmniej w IE11):

Gdy konsola nie jest otwarta, IE wykonuje dość agresywne buforowanie, więc upewnij się, że wszystkie $.ajaxpołączenia lub XMLHttpRequestpołączenia mają ustawioną wartość false.

Na przykład:

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

Gdy konsola programisty jest otwarta, buforowanie jest mniej agresywne. Wygląda na błąd (a może funkcję?)

użytkownik3916095
źródło
9
To mnie właśnie uratowało;) Dzięki! Powiedziałbym, że to błąd, ponieważ powinieneś mieć takie same warunki do testowania i debugowania swojej witryny przy otwartej i zamkniętej konsoli.
Chnoch
Pracował dla mnie. W szczególności: stackoverflow.com/questions/13391563/…
user1062589
2
powinno to być wyższe, ponieważ uważam, że jest to rzeczywista odpowiedź ... zaakceptowana odpowiedź w odniesieniu do console.log w niektórych wersjach IE wyrzuci błąd, nie powodując opisanego tutaj zachowania.
Migs,
63

To rozwiązało mój problem po niewielkiej zmianie. Dodałem następujące na mojej stronie HTML, aby naprawić problem IE9:

<script type="text/javascript">
    // IE9 fix
    if(!window.console) {
        var console = {
            log : function(){},
            warn : function(){},
            error : function(){},
            time : function(){},
            timeEnd : function(){}
        }
    }
</script>
runeks
źródło
1
To rozwiązanie nie działa w przeglądarce IE 11 w systemie Windows 7 64-bit.
Vikram
1
To rozwiązało mój problem z IE 11 na Windows 7 64-bit.
zonyang
29

Oprócz consoleproblemu dotyczącego używania wspomnianego w zaakceptowanej odpowiedzi i innych, istnieje co najmniej inny powód, dla którego czasami strony w Internet Explorerze działają tylko z aktywowanymi narzędziami programistycznymi.

Gdy narzędzia programistyczne są włączone, IE tak naprawdę nie używa pamięci podręcznej HTTP (przynajmniej domyślnie w IE 11), jak w trybie normalnym.

Oznacza to, że jeśli Twoja witryna lub strona ma problem z buforowaniem (jeśli buforuje więcej niż powinien, na przykład - tak było w moim przypadku), nie zobaczysz tego problemu w trybie F12. Więc jeśli javascript wykonuje niektóre buforowane żądania AJAX, mogą nie działać zgodnie z oczekiwaniami w trybie normalnym i działać poprawnie w trybie F12.

Simon Mourier
źródło
1
Zobacz stackoverflow.com/questions/3984961/…, aby dowiedzieć się, jak wyłączyć buforowanie żądań xmlHttpReq.
Michael Ross
1
Słodkie. To zadziwiająco zadziałało. Chyba usługa $ http Angulara nie buforuje biustu tak, jak myślałem.
17

Myślę, że to może pomóc, dodając to przed dowolnym tagiem javascript:

try{
  console
}catch(e){
   console={}; console.log = function(){};
}
todotresde
źródło
11
try catchwykrycie, że zmienna istnieje, jest złym pomysłem. Jest nie tylko powolny, ale jeśli masz więcej niż jedną instrukcję w swoim bloku try, możesz otrzymać wyjątek z innego powodu. Nie używaj tego, przynajmniej użyjif (typeof console == 'undefined')
Juan Mendes
8

Jeśli używasz AngularJS w wersji 1.X, możesz skorzystać z usługi $ log zamiast bezpośrednio z pliku console.log.

Prosta usługa logowania. Domyślna implementacja bezpiecznie zapisuje komunikat w konsoli przeglądarki (jeśli jest dostępna).

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

Więc jeśli masz coś podobnego do

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

możesz go zastąpić

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

Angular 2+ nie ma wbudowanej usługi logowania .

Oskar S.
źródło
pomogło mi to, dziękuję - dla kogokolwiek innego używającego maszynopisu, jest to „ILogService” w definicjach kątowych
DannykPowell
IIRC za pomocą $ log powoduje, że lokalizacja instrukcji dziennika jest zasłonięta, w przeciwieństwie do korzystania z pliku console.log. Nie tak świetne z mojego doświadczenia podczas programowania.
JesseDahl
5

Jeśli używasz angulari np. 9, 10Lub edgeużywasz:

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';
}]);

Aby całkowicie wyłączyć cache.

Itsik Mauyhas
źródło
4

Zdarzyło mi się to w IE 11. Dzwoniłem do funkcji .load jquery. Zrobiłem to po staremu i umieściłem coś w adresie URL, aby wyłączyć buforowanie.

$("#divToReplaceHtml").load('@Url.Action("Action", "Controller")/' + @Model.ID + "?nocache=" + new Date().getTime());
Vilhelm
źródło
2

Mam jeszcze jedną alternatywę dla rozwiązań oferowanych przez runeks i todotresde, która pozwala także uniknąć pułapek omawianych w komentarzach do odpowiedzi Spudleya :

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

Jest nieco niechlujny, ale z drugiej strony jest zwięzły i obejmuje wszystkie metody logowania zawarte w odpowiedzi runeks i ma tę ogromną zaletę, że można otworzyć okno konsoli IE w dowolnym momencie i dzienniki napływają.

schnatterer
źródło
0

Wystąpił ten problem w IE 11 w systemie Windows 7 i Windows 10. Odkryliśmy, na czym dokładnie polegał problem, włączając funkcje debugowania dla IE (IE> Opcje internetowe> karta Zaawansowane> Przeglądanie> Odznacz Wyłącz debugowanie skryptu (Internet Explorer) ). Ta funkcja jest zwykle sprawdzana w naszym środowisku przez administratorów domeny.

Problem polegał na tym, że używaliśmy tej console.debug(...)metody w naszym kodzie JavaScript. Założeniem przyjętym przez programistę (mnie) było to, że nie chciałem niczego pisać, jeśli konsola narzędzi programistycznych klienta nie była jawnie otwarta. Chociaż Chrome i Firefox wydawały się zgadzać z tą strategią, IE 11 nie spodobało się jej ani trochę. Zmieniając wszystkie console.debug(...)instrukcje na console.log(...)instrukcje, byliśmy w stanie nadal rejestrować dodatkowe informacje w konsoli klienta i wyświetlać je, gdy były otwarte, ale w inny sposób ukrywać je przed typowym użytkownikiem.

Gregsonian
źródło
0

Ustawiam rozdzielczość i naprawiam problem. Wygląda na to, że żądanie AJAX, które wstawiłem do JavaScript, nie było przetwarzane, ponieważ moja strona miała problem z pamięcią podręczną. jeśli Twoja witryna lub strona ma problem z pamięcią podręczną, nie zobaczysz tego problemu w trybie programisty / F12. moje buforowane żądania AJAX JavaScript mogą nie działać zgodnie z oczekiwaniami i powodować awarię wykonywania, która nie ma żadnego problemu z F12. Właśnie dodałem nowy parametr, aby bufor był fałszywy.

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

Wygląda na to, że IE musi to być fałsz, aby działanie AJAX i javascript działało poprawnie.

pauldx
źródło