650

IE9 Bug - JavaScript only works after opening developer tools once.

Our site offers free pdf downloads to users, and it has a simple "enter password to download" function. However, it doesn't work at all in Internet Explorer.

You can see for yourself in this example.

The download pass is "makeuseof". In any other browser, it works fine. In IE, both buttons do nothing.

The most curious thing I've found is that if you open and close the developer toolbar with F12, it all suddenly starts to work.

We've tried compatibility mode and such, nothing makes a difference.

How do I make this work in Internet Explorer?

fragilewindows
  • 1,324
  • 1
  • 13
  • 25
James Bruce
  • 6,615
  • 3
  • 13
  • 8
  • 3
    use cross-browser wrapper: https://github.com/MichaelZelensky/log.js – Michael Zelensky Feb 18 '14 at 16:15
  • 1
    A good alternative, if you have a build step, is to use something like `gulp-strip-debug`. It removes all `console.*` methods, great for production builds, or testing in IE. – knownasilya Jul 13 '14 at 02:05
  • 15
    For future googlers: I had the same symptoms, but in IE11. Well, it turned out that the answer was not related to `console`, but to my use of angular and caching of get requests. See answers [here](http://stackoverflow.com/questions/16098430) and [here](http://stackoverflow.com/questions/16971831) for more. – Christoffer Lette Sep 10 '14 at 19:49
  • @ChristofferLette Yes, i have the same issue please check http://stackoverflow.com/questions/31428126/not-getting-object-file-from-a-file-input-html-control-using-jquery-and-javasc.....The code works properly when developers tools is opened.. – PPB Jul 15 '15 at 13:38
  • 7
    The most annoying thing about problems like this? They're almost impossible to debug because it starts working as soon as you open the developer console. – jlewkovich Nov 04 '16 at 13:40

12 Answers12

822

It sounds like you might have some debugging code in your javascript.

The experience you're describing is typical of code which contain console.log() or any of the other console functionality.

The console object is only activated when the Dev Toolbar is opened. Prior to that, calling the console object will result in it being reported as undefined. After the toolbar has been opened, the console will exist (even if the toolbar is subsequently closed), so your console calls will then work.

There are a few solutions to this:

The most obvious one is to go through your code removing references to console. You shouldn't be leaving stuff like that in production code anyway.

If you want to keep the console references, you could wrap them in an if() statement, or some other conditional which checks whether the console object exists before trying to call it.

Spudley
  • 157,081
  • 38
  • 222
  • 293
  • 8
    Are there any workarounds for leaving debugging code in? IE is the only browser with this inane behavior... – Meekohi Feb 21 '12 at 23:27
  • 94
    `if(!console) {console={}; console.log = function(){};}` – Meekohi Feb 21 '12 at 23:40
  • 80
    @Meekohi `if(!console)` will cause the same error - it should read `if(!window.console)` – mindplay.dk Aug 14 '12 at 12:55
  • @btevfik - I'm glad the answer helped you, but it's a little unfair to knock IE for this. IE works this way for backward compatibility reasons -- older IE versions did not have the console feature, and some third party scripts exist that replicate it (eg Firebug Lite). Having the console object declared by default would have broken those scripts, which would have been unpopular with developers that wanted to use them. IE's behaviour of creating the console object when the dev tools window is opened is a good compromise to this. – Spudley Apr 12 '13 at 21:12
  • 9
    so... IE should didn't implement a feature that every new js dev uses all the time, to avoid annoying a few devs that used a script to fix the thing that should have worked in the first place... but it's unfair to knock IE for that? You are a very generous person Spudley!!! :) – Jordan Davis Feb 06 '15 at 13:38
  • 1
    @jorjordandan - well, you can't really knock old IE for it; you'd have the same issue if you were trying to debug using an old version of Firefox. It's just that nobody uses Firefox 3 any more. – Spudley Feb 08 '15 at 19:13
  • `console = window.console || { log: function(){} }` – antoine129 Apr 23 '15 at 09:20
  • 3
    `if(!window.console) {console={}; console.log = function(){};}` My god, this just fixed this annoying issue with my code not working on IE8&9 when the user directly opened my site as the start site. It seems on IE10 and 11 this isn't an issue anymore. – regeter May 08 '15 at 22:06
  • 1
    Came here from google via a search for: "ie problem goes away when opening dev tools f12" This has solved a problem which I couldn't reproduce on any version of IE I had, but which was cropping up at the client. It's also impossible to debug, because opening dev tools to find out what's going on causes the problem to go away. Thanks so much; I wish I could up this by more than one. – daf Oct 02 '15 at 06:25
  • @Spudley the funny thing is, chrome was the first one to release the console and they didn't do anything crazy like this for "backward compatibility", yet IE8 came with this weird behavior. Then firefox 4 added the cosole too and still nothing crazy, and IE9 still had this weird console behaviour: http://caniuse.com/#search=console – Ziul Nov 17 '15 at 18:39
  • @Ziul - actually, the original console that they all copy from is the Firebug plugin for Firefox, which was available way back for Firefox 1.5, (possibly even earlier?) a long time before Chrome was released. Back when Firebug came out it had exactly this behaviour, so IE's behaviour is not out of context for the time. Yes, it seems bad now, but it wasn't at the time. (and anyway, if you aren't prepared for bad browser behaviour, you shouldn't be working in old IE versions anyway, right?) – Spudley Nov 17 '15 at 20:29
  • @Spudley It wasn't like this in the IE8 beta, they just gave us a big surprice when they released it like this... – Ziul Nov 17 '15 at 22:01
  • I have same problem in Safari 9.x (earlier versions works fine). but none of these solutions worked for me – HaBo Mar 16 '16 at 15:11
  • 7
    Still happens with IE11 – Michael Sep 30 '16 at 11:55
163

HTML5 Boilerplate has a nice pre-made code for console problems fixing:

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

As @plus- pointed in comments, latest version is available on their GitHub page

Christoffer Lette
  • 12,919
  • 7
  • 46
  • 54
Tallmaris
  • 7,485
  • 3
  • 25
  • 57
  • 9
    The link in @plus' comment is no longer valid. The code has been pushed down into a `src` sub-dir: https://github.com/h5bp/html5-boilerplate/blob/master/src/js/plugins.js – Christoffer Lette Sep 10 '14 at 13:48
  • It's since been removed from the HTML5 Boilerplate repo. The last version was [this one](https://github.com/h5bp/html5-boilerplate/blob/8f0adb5dedd070b02de5c47ac8e7acc5ff73f516/dist/js/plugins.js) – CrazyPenguin Dec 21 '20 at 18:56
153

Here's another possible reason besides the console.log issue (at least in IE11):

When the console is not open, IE does pretty aggressive caching, so make sure that any $.ajax calls or XMLHttpRequest calls have caching set to false.

For example:

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

When the developer console is open, caching is less aggressive. Seems to be a bug (or maybe a feature?)

user3916095
  • 1,531
  • 1
  • 8
  • 2
  • 9
    This just saved me ;) Thanks! I'd say it's a bug since you should have the same conditions to test and debug your website with the console open and close. – Chnoch Mar 06 '15 at 11:35
  • Worked for me. Specifically: http://stackoverflow.com/questions/13391563/how-to-set-cache-false-for-getjson-in-jquery – user1062589 Nov 16 '16 at 22:51
  • 2
    this should be higher as I think is the actual answer... the accepted answer in regards to console.log in some IE version will throw an error, not caused the behavior described here. – Migs Aug 23 '17 at 15:50
62

This solved my problem after I made a minor change to it. I added the following in my html page in order to fix the IE9 problem:

<script type="text/javascript">
    // IE9 fix
    if(!window.console) {
        var console = {
            log : function(){},
            warn : function(){},
            error : function(){},
            time : function(){},
            timeEnd : function(){}
        }
    }
</script>
Kiquenet
  • 13,271
  • 31
  • 133
  • 232
runeks
  • 621
  • 5
  • 2
28

Besides the 'console' usage issue mentioned in accepted answer and others,there is at least another reason why sometimes pages in Internet Explorer work only with the developer tools activated.

When Developer Tools is enabled, IE doesn't really uses its HTTP cache (at least by default in IE 11) like it does in normal mode.

It means if your site or page has a caching problem (if it caches more than it should for example - that was my case), you will not see that problem in F12 mode. So if the javascript does some cached AJAX requests, they may not work as expected in normal mode, and work fine in F12 mode.

Simon Mourier
  • 117,251
  • 17
  • 221
  • 269
  • 1
    See http://stackoverflow.com/questions/3984961/prevent-xmlhttpreq-s-browser-caching for how to disable caching xmlHttpReq requests. – Michael Ross Jun 16 '14 at 20:55
  • 1
    Sweet. This surprisingly worked. I guess Angular's $http service does not cache bust as I thought it would. –  Jun 19 '14 at 16:01
16

I guess this could help, adding this before any tag of javascript:

try{
  console
}catch(e){
   console={}; console.log = function(){};
}
Kiquenet
  • 13,271
  • 31
  • 133
  • 232
todotresde
  • 1,620
  • 2
  • 19
  • 25
  • 11
    `try catch` to detect that a variable exists is a bad idea. Not only is it slow, but if you have more than one statement in your try block, you could get an exception for a different reason. Don't use this, at the very least use `if (typeof console == 'undefined')` – Juan Mendes May 15 '14 at 22:23
7

If you are using AngularJS version 1.X you could use the $log service instead of using console.log directly.

Simple service for logging. Default implementation safely writes the message into the browser's console (if present).

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

So if you have something similar to

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

you can replace it with

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

Angular 2+ does not have any built-in log service.

Oskar S.
  • 89
  • 1
  • 6
  • this helped me, thanks- for anyone else using typescript, this is the "ILogService" in the angular definitions – DannykPowell Jun 07 '16 at 16:14
  • IIRC using $log causes the location of the log statement to be obscured, unlike when using console.log. Not so great from my experience during development. – JesseDahl Mar 06 '18 at 20:33
5

If you are using angular and ie 9, 10 or edge use :

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

To completely disable cache.

Itsik Mauyhas
  • 3,163
  • 7
  • 48
  • 93
3

It happened in IE 11 for me. And I was calling the jquery .load function. So I did it the old fashion way and put something in the url to disable cacheing.

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

I got yet another alternative for the solutions offered by runeks and todotresde that also avoids the pitfalls discussed in the comments to Spudley's answer:

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

It's a bit scruffy but on the other hand it's concise and covers all the logging methods covered in runeks' answer and it has the huge advantage that you can open the console window of IE at any time and the logs come flowing in.

Community
  • 1
  • 1
schnatterer
  • 6,520
  • 6
  • 53
  • 71
0

We ran into this problem on IE 11 on Windows 7 and Windows 10. We discovered what exactly the problem was by turning on debugging capabilities for IE (IE > Internet Options > Advanced tab > Browsing > Uncheck Disable script debugging (Internet Explorer)). This feature is typically checked on within our environment by the domain admins.

The problem was because we were using the console.debug(...) method within our JavaScript code. The assumption made by the developer (me) was I did not want anything written if the client Developer Tools console was not explicitly open. While Chrome and Firefox seemed to agree with this strategy, IE 11 did not like it one bit. By changing all the console.debug(...) statements to console.log(...) statements, we were able to continue to log additional information in the client console and view it when it was open, but otherwise keep it hidden from the typical user.

gregsonian
  • 728
  • 11
  • 13
0

I put the resolution and fix for my issue . Looks like AJAX request that I put inside my JavaScript was not processing because my page was having some cache problem. if your site or page has a caching problem you will not see that problem in developers/F12 mode. my cached JavaScript AJAX requests it may not work as expected and cause the execution to break which F12 has no problem at all. So just added new parameter to make cache false.

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

Looks like IE specifically needs this to be false so that the AJAX and javascript activity run well.

pizzaisdavid
  • 381
  • 2
  • 12
pauldx
  • 381
  • 1
  • 2
  • 17