Binary files corrupted – How to Download Binary Files with AngularJS

The question:

download any file using ResponseEntity with angular does not work

I need to download a file using angular in client side,
this file can have any format it could be a pdf or excel or image or txt …
my method works just for txt files and gives me a fail format for excel and image and for the pdf it gives an empty pdf.

so in my controller here is the function that calles the service method:

    vm.downloadFile = downloadFile;

    function downloadFile(file){
        var urlDir = "C://STCI//"+idpeticion;
        return VerDocServices.downloadFile(file,urlDir)
          .then(function(response) {
            var data =;
            var filename = file;
            var contentType = 'application/octet-stream';//octet-stream             
            var linkElement = document.createElement('a');
            try {
                var blob = new Blob([ data ], {
                    type : contentType
                var url = window.URL.createObjectURL(blob);
                linkElement.setAttribute('href', url);
                linkElement.setAttribute("download", filename);
                var clickEvent = new MouseEvent("click", {
                    "view" : window,
                    "bubbles" : true,
                    "cancelable" : false
            } catch (ex) {
                throw ex;
        }).catch(function(response) {
            alert('Se ha producido un error al exportar del documento');
            throw response;

and my service.js has:

angular.module('mecenzApp').service('VerDocServices',['$http',function($http) {

this.downloadFile = function(file,urlDir) {

    return $http.get('api/downloadFile', {
        params : {
            file : file,
            urlDir : urlDir
    }); }} ]);

And my service method is this:

public ResponseEntity<byte[]> downloadFile(@RequestParam(value = "file") String file, @RequestParam(value = "urlDir") String urlDir) {
    log.debug("GET ---------------- DOWNLOAD FILE : {}", file);
    log.debug("GET ---------------- From the DIRECTORY: {}",urlDir);

    InputStream fileStream;
    String filepath = urlDir+File.separator+file;
    try {
        File f = new File(filepath);
        log.debug("GET ---------------- FILE: {}",f.getPath());
        fileStream = new FileInputStream(f);
        byte[] contents = IOUtils.toByteArray(fileStream);
        HttpHeaders headers = new HttpHeaders();
        String filename = file;
        headers.setContentDispositionFormData(filename, filename);
        ResponseEntity<byte[]> response2 = new ResponseEntity<byte[]>(contents, headers, HttpStatus.OK);
        return response2;            
    } catch (FileNotFoundException e) {
    } catch (IOException e) {
   return null;

could you plz take a look and tell me what did I have missed??

Thank youuu 🙂

The Solutions:

Below are the methods you can try. The first solution is probably the best. Try others if the first one doesn’t work. Senior developers aren’t just copying/pasting – they read the methods carefully & apply them wisely to each case.

Method 1

How to Download Binary Files with AngularJS

When downloading binary files, it is important to set the responseType:

app.service('VerDocServices',['$http',function($http) {

    this.downloadFile = function(url, file, urlDir) {
        var config = {
            //SET responseType
            responseType: 'blob',
            params : {
                file : file,
                urlDir : urlDir

        return $http.get(url, config)
          .then(function(response) {
        }).catch(function(response) {
            console.log("ERROR: ", response.status);
            throw response;

If the responseType is omitted the XHR API defaults to converting UTF-8 encoded text to DOMString (UTF-16) which will corrupt PDF, image, and other binary files.

For more information, see MDN Web API Reference – XHR ResponseType

Method 2

I don’t know much about the backend, but I’ll provide what i have used may be it will help, so On the Java Script File:

//your $http(request...)

.success(function (data, status, headers, config) {
  //Recieves base64 String data
  var fileName = 'My Awesome File Name'+'.'+'pdf';

  //Parsing base64 String...
  var binaryString =  window.atob(data);
  var binaryLen = binaryString.length;
  var fileContent = new Uint8Array(binaryLen);
  for (var i = 0; i < binaryLen; i++)        {
     var ascii = binaryString.charCodeAt(i);
     fileContent[i] = ascii;
  var blob = new Blob([fileContent], { type: 'application/octet-stream' }); //octet-stream
  var fileURL = window.URL.createObjectURL(blob);
  $sce.trustAsResourceUrl(fileURL);  //allow angular to trust this url
  //Creating the anchor download link
  var anchor = angular.element('<a/>');
  anchor.css({display: 'none'}); // Make sure it's not visible
  angular.element(document.body).append(anchor); // Attach it to the document
    href: fileURL,
    target: '_blank',
    download: fileName
  anchor.remove(); // Clean it up afterwards

And On your backend, make sure that your webservice produces octet-stream and returning the file in base64 data format, i did this using Java JAX-RS like this:

public Response downloadFile(...){
  String base64String = Base64.getEncoder().encodeToString(/*here you pass your file in byte[] format*/);
  return Response.ok(base64String).build();

All methods was sourced from or, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Comment