title: Download file from server with angular $http.get
body: <p>I am trying to trigger a file download when a user clicks on a "Download PDF" button. A call is made to the API which makes a few checks, and then returns the file. I don't want the file to open in the browser. I have read a lot of stackoverflow-questions about how to do this, but can't get it to work. I get the file content as text back, but the browser doesn't save the file, nor gives me the choice to save it as a file.</p>
  
  <p>This is what I have.</p>
  
  <p><strong>HTML</strong></p>
  
  <pre><code>&lt;button ng-click="apiDownload()"&gt;Download PDF&lt;/button&gt;
  </code></pre>
  
  <p><strong>AngularJS controller</strong></p>
  
  <pre><code>$scope.apiDownload = function(){
      var config = {
          method: 'GET',
          url: "/api/download",
          headers: {
              'Accept': 'application/pdf'
          }
      };
      $http(config)
          .success(function(res){
              console.log(res);
          })
          .error(function(res){});
  };
  </code></pre>
  
  <p><strong>PHP API</strong> (mostly from <a href="http://davidwalsh.name/php-force-download" rel="nofollow"><strong>here</strong></a>)</p>
  
  <pre class="lang-php prettyprint-override"><code>function apiDownloadFile() {
      $file_name = "download/test.pdf";
      $abs_file_name = realpath(dirname(__FILE__)).'/'.$file_name;
      if(is_file($abs_file_name) &amp;&amp; file_exists($abs_file_name)) {
  
          // required for IE
          if(ini_get('zlib.output_compression')) { ini_set('zlib.output_compression', 'Off'); }
  
          // get the file mime type using the file extension
          switch(strtolower(substr(strrchr($file_name, '.'), 1))) {
              case 'pdf': $mime = 'application/pdf'; break;
              case 'zip': $mime = 'application/zip'; break;
              case 'jpeg':
              case 'jpg': $mime = 'image/jpg'; break;
              default: $mime = 'application/force-download';
          }
          header('Pragma: public');   // required
          header('Expires: 0');       // no cache
          header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
          header('Last-Modified: '.gmdate ('D, d M Y H:i:s', filemtime ($abs_file_name)).' GMT');
          header('Cache-Control: private',false);
          header('Content-Type: '.$mime);
          header('Content-Disposition: attachment; filename='.basename($abs_file_name));
          header('Content-Transfer-Encoding: binary');
          header('Content-Length: '.filesize($abs_file_name));    // provide file size
          header('Connection: close');
          readfile($abs_file_name);       // push it out
          exit();
      }
  
  }
  </code></pre>
  
  <p>I see these headers in chrome developer tools:</p>
  
  <p><strong>Request Headers</strong></p>
  
  <pre><code>GET /api/download HTTP/1.1
  Host: sa.dev
  Connection: keep-alive
  Cache-Control: no-cache
  Pragma: no-cache
  Accept: application/pdf
  If-Modified-Since: 0
  User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.89 Safari/537.36
  Referer: https://sa.dev/insights
  Accept-Encoding: gzip, deflate, sdch
  Accept-Language: en-US,en;q=0.8,da;q=0.6,sv;q=0.4,no;q=0.2,nb;q=0.2
  Cookie: ...
  </code></pre>
  
  <p><strong>Response Headers</strong></p>
  
  <pre><code>HTTP/1.1 200 OK
  Date: Mon, 16 Mar 2015 14:27:08 GMT
  Server: Apache/2.4.9 (Unix) PHP/5.6.5 OpenSSL/0.9.8zc
  X-Powered-By: PHP/5.6.5
  Pragma: public
  Expires: 0
  Cache-Control: must-revalidate, post-check=0, pre-check=0
  Last-Modified: Mon, 16 Mar 2015 09:04:06 GMT
  Cache-Control: private
  Content-Disposition: attachment; filename=test.pdf
  Content-Transfer-Encoding: binary
  Content-Length: 5501633
  Connection: close
  Content-Type: application/pdf
  </code></pre>