title: Client download of a server generated zip file
body: <p>Before somebody says, "duplicate", I just want to make sure, that folks know, that I have already reviewed these questions:</p>
  
  <p>1) Uses angular and php, not sure what is happening here (I don't know PHP): <a href="https://stackoverflow.com/questions/26572031/download-zip-file-and-trigger-save-file-dialog-from-angular-method">Download zip file and trigger &quot;save file&quot; dialog from angular method</a></p>
  
  <p>2) Can't get this answer to do anything: <a href="https://stackoverflow.com/questions/30158115/how-to-download-a-zip-file-using-angular">how to download a zip file using angular</a></p>
  
  <p>3) This person can already download, which is past the point I'm trying to figure out: 
  <a href="https://stackoverflow.com/questions/22459045/download-external-zip-file-from-angular-triggered-on-a-button-action">Download external zip file from angular triggered on a button action</a></p>
  
  <p>4) No answer for this one:
  <a href="https://stackoverflow.com/questions/30802866/download-zip-file-from-server-in-nodejs">download .zip file from server in nodejs</a></p>
  
  <p>5) I don't know what language this even is:
  <a href="https://stackoverflow.com/questions/35596764/zip-file-download-using-angularjs-directive">https://stackoverflow.com/questions/35596764/zip-file-download-using-angularjs-directive</a></p>
  
  <p><strong>Given those questions</strong>, if this is still a duplicate, I apologize.  Here is, yet, another version of this question.</p>
  
  <p>My angular 1.5.X client gives me a list of titles, of which each have an associated file.  My Node 4.X/Express 4.X server takes that list, gets the file locations, creates a zip file, using express-zip from npm, and then streams that file back in the response.  I then want my client to initiate the browser's "download a file" option.  </p>
  
  <p>Here's my client code (Angular 1.5.X):</p>
  
  <pre><code>function bulkdownload(titles){
      titles = titles || [];
      if ( titles.length &gt; 0 ) {
          $http.get('/query/bulkdownload',{
              params:{titles:titles},
              responseType:'arraybuffer'
          })
          .then(successCb,errorCb)
          .catch(exceptionCb);
      }
  
      function successCb(response){
          // This is the part I believe I cannot get to work, my code snippet is below
      };
  
      function errorCb(error){
              alert('Error: ' + JSON.stringify(error));
      };
  
      function exceptionCb(ex){
              alert('Exception: ' + JSON.stringify(ex));
      };
  };
  </code></pre>
  
  <p>Node (4.X) code with <em>express-zip</em>, <a href="https://www.npmjs.com/package/express-zip" rel="noreferrer">https://www.npmjs.com/package/express-zip</a>:</p>
  
  <pre><code>router.get('/bulkdownload',function(req,resp){
      var titles = req.query.titles || [];
  
      if ( titles.length &gt; 0 ){
          utils.getFileLocations(titles).
          then(function(files){
              let filename = 'zipfile.zip';
  
              // .zip sets Content-Type and Content-disposition
              resp.zip(files,filename,console.log);
          },
          _errorCb)
      }
  });
  </code></pre>
  
  <p>Here's my successCb in my client code (Angular 1.5.X):</p>
  
  <pre><code>function successCb(response){
      var URL = $window.URL || $window.webkitURL || $window.mozURL || $window.msURL;
      if ( URL ) {
          var blob = new Blob([response.data],{type:'application/zip'});
          var url = URL.createObjectURL(blob);
          $window.open(url);
      }
  };
  </code></pre>
  
  <p>The "blob" part seems to work fine.  Checking it in IE's debugger, it does look like a file stream of octet information.  Now, I believe I need to get that blob into the some HTML5 directive, to initiate the "Save File As" from the browser.  Maybe?  Maybe not?</p>
  
  <p>Since 90%+ of our users are using IE11, I test all of my angular in PhantomJS (Karma) and IE.  When I run the code, I get the old "Access is denied" error in an alert window:</p>
  
  <pre><code>Exception: {"description":"Access is denied...&lt;stack trace&gt;}
  </code></pre>
  
  <p>Suggestions, clarifications, answers, etc. are welcome!</p>