title: AngularJS Node app downloads instead of loading in Internet Explorer
body: <p>Whenever I try loading my AngularJS webpage (on a node js + express server) through <code>http://localhost:3000</code>, Internet Explorer just tries to <strong>download</strong> it with a random name and no file extension, instead of showing the actual page.</p>
  
  <p>I can't even check the console for errors, because the download attempt seems to start before even trying to load it as a webpage.</p>
  
  <p>The website works perfectly on both Firefox and Chrome. I am using Internet Explorer <em>11</em>, so it's not even an old version.</p>
  
  <p>I tried running my index through the <a href="https://validator.w3.org/" rel="nofollow noreferrer">W3 Validator</a>, and the only errors it points out in the DOM are the Angular directives and tags (which are not really errors).</p>
  
  <p>I tried changing the DOCTYPE from just a simple <code>&lt;!DOCTYPE html&gt;</code> to this:</p>
  
  <pre><code>&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-loose.dtd"&gt;
  </code></pre>
  
  <p>And this:</p>
  
  <pre><code>&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
  </code></pre>
  
  <p>... and this:</p>
  
  <pre><code>&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"&gt;
  </code></pre>
  
  <p>To no effect.</p>
  
  <p>As suggested in other questions, I also tried serving my page as "text/plain" rather than "text/html" in my node server, but that didn't help either.</p>
  
  <p>Here's the html for my index:</p>
  
  <pre><code>&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-loose.dtd"&gt;
  &lt;html xmlns="http://www.w3.org/1999/xhtml" lang="it"&gt;
      &lt;head&gt;
          &lt;meta content="text/html; charset=utf-8" http-equiv="content-type"/&gt;
          &lt;!-- Angular Material CSS now available via Google CDN; version 1.0.7 used here --&gt;
          &lt;link rel="stylesheet" href="./modules/angular-material/angular-material.min.css"/&gt;
          &lt;link rel="stylesheet" href="./css/style.css"/&gt;
          &lt;link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons"/&gt;
      &lt;link rel="icon" href="icons/favicon.ico" type="image/x-icon"/&gt;
          &lt;base href="/"/&gt;
          &lt;title&gt;Area Clienti&lt;/title&gt;
          &lt;script src="./modules/angular/angular.js" type="text/javascript"&gt;&lt;/script&gt;
  
          &lt;script src="./modules/ngstorage/ngStorage.js" type="text/javascript"&gt;&lt;/script&gt;
  
          &lt;script src="./modules/angular-aria/angular-aria.min.js" type="text/javascript"&gt;&lt;/script&gt;
          &lt;script src="./modules/angular-animate/angular-animate.min.js" type="text/javascript"&gt;&lt;/script&gt;
  
          &lt;script src="./modules/angular-material/angular-material.min.js" type="text/javascript"&gt;&lt;/script&gt;
  
          &lt;script src="./modules/angular-ui-router/release/angular-ui-router.min.js" type="text/javascript"&gt;&lt;/script&gt;
          &lt;script src="./modules/ui-router-extras/release/modular/ct-ui-router-extras.core.min.js" type="text/javascript"&gt;&lt;/script&gt;
          &lt;script src="./modules/ui-router-extras/release/modular/ct-ui-router-extras.dsr.min.js" type="text/javascript"&gt;&lt;/script&gt;
          &lt;script src="./modules/ui-router-extras/release/modular/ct-ui-router-extras.sticky.min.js" type="text/javascript"&gt;&lt;/script&gt;
  
          &lt;script src="./modules/pdfmake/build/pdfmake.min.js" type="text/javascript"&gt;&lt;/script&gt;
          &lt;script src="./modules/pdfmake/build/vfs_fonts.js" type="text/javascript"&gt;&lt;/script&gt;
  
          &lt;script src="./modules/angular-messages/angular-messages.min.js" type="text/javascript"&gt;&lt;/script&gt;
          &lt;script src="http://ngmaterial.assets.s3.amazonaws.com/svg-assets-cache.js" type="text/javascript"&gt;&lt;/script&gt;
  
          &lt;script src="./js/client.js" type="text/javascript"&gt;&lt;/script&gt;
      &lt;/head&gt;
      &lt;body ng-app="App" ng-controller="AppCtrl" ng-view ui-view ng-cloak layout="row"&gt;
      &lt;/body&gt;
  &lt;/html&gt;
  </code></pre>
  
  <p>The script tags were in the body before, I tried putting them in the head to see if that would have helped, but it didn't.</p>
  
  <p>What might be the issue here? And why is it so painful to make stuff work on IE?</p>
  
  <p>EDIT: here's the server code.</p>
  
  <pre><code>var express = require("express");
  var fs = require('fs');
  var xml2js = require("./node_modules/xml2js");
  var auth = require("./authenticator.js");
  var bodyParser = require('body-parser');
  
  var app=express();
  
  //app.use(express.static('pages'));
  
  var server = app.listen(3000, function(){
     var host = server.address().address;
     var port = server.address().port;
  });
  
  var jsonParser = bodyParser.json();       // to support JSON-encoded bodies
  
  var urlencodedParser = bodyParser.urlencoded({     // to support URL-encoded bodies
      extended: true
  }); 
  app.get('/', function(req, res){
      sendFile(res, './index.html', getHeader('text/plain'));
  });
  
  app.use('/font/', express.static('./font/'));
  app.use('/modules/', express.static('./node_modules/'));
  app.use('/css/', express.static('./css/'));
  app.use('/views/', express.static('./views/'));
  app.use('/img/', express.static('./img/'));
  app.use('/js/', express.static('./js/'));
  
  function sendFile(res, path, header){
      fs.readFile(path, function(err, content){
          if(err) {
              console.log("\nErrore caricando " + path + " - err: " + err);
              //pageNotFound(res, "error");
          }
          else sendToClient(content, res, 200, header);
      });
  }
  
  function getHeader(type){
      return {"Content-Type": type};
  }
  
  function sendToClient(data, res, code, type){
      res.writeHead(code, getHeader(type));
      (type === "text/html" || type === "text") ? res.end(data, "utf-8") : res.end(data);
  }
  </code></pre>
  
  <p>Plus a bunch of other POST and GET services which I think are not relevant</p>
  
  <hr>
  
  <p><strong>UPDATE:</strong> I managed to get it to say something in the developer console. This is the error:</p>
  
  <p><a href="https://i.stack.imgur.com/DOa7B.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/DOa7B.png" alt="error when loading"></a></p>
  
  <p>(translation: impossible to open <a href="http://localhost:3000/" rel="nofollow noreferrer">http://localhost:3000/</a>)
  It still tries to download the page.</p>
  
  <hr>
  
  <p><strong>UPDATE 2</strong>:</p>
  
  <p>I managed to find out what the issue was: for some reason, the Content-Type header content was being interpreted as an object rather than the string it actually was, so IE couldn't render the page.</p>
  
  <p>It now renders the index, but Angular-UI-Router doesn't seem to work. </p>
  
  <p>It appears as though ui-router can't load sub states (it can switch between normal states though, since I was able to log in and be transferred to my dashboard page, which is a different state)</p>
  
  <p>(Everything is still working perfectly fine on Chrome and Firefox)</p>