user2061057
user2061057

Reputation: 1022

Angular 2: Downloading a ZIP as blob fails

I guess my back-end works, because this works and the zip is fine:

curl -X POST -H 'Content-Type: application/json' -d '{}' http://localhost:3000/zip/create > file.zip

My Django back-end returns the data like this:

return HttpResponse(data, content_type='application/octet-stream')

I cannot figure out what's wrong in my Angular 2 code, because the ZIP it gets ends up being somehow corrupted and I cannot open it.

The actual data seems to be in response._body:

let blob = new Blob([response._body], { "type": 'application/octet-stream;' });

this.exportUrl = this.sanitizer.bypassSecurityTrustUrl(URL.createObjectURL(blob));

this.exportFileName = "download.zip";

After clicking that URL it downloads the zip but it doesn't work. So apparently I handle the binary data somehow incorrectly?

My service is essentially this:

return this.http.post(
    this.zipUrl,
    JSON.stringify(zipCreationParameters),
    {headers: {'Content-Type': 'application/json'} });

Upvotes: 1

Views: 1475

Answers (2)

Naga Sarath Chand
Naga Sarath Chand

Reputation: 83

well, very important thing you need to consider is: in backend encode your UTF-8 content to Base64 and then send it as produces="application/zip". as frontend atob function supports base64 but not utf

because what you receive in the uI response._body is bytestring. now decode it as decode(atob(your content here)). after that take each bytecharacter and put it in Uint8Array. THATS IT. it works for me perfectly after 1 day of research.

function convertDataURIToBinary(dataURI) {
  var base64Index = dataURI.indexOf(BASE64_MARKER) + BASE64_MARKER.length;
  var base64 = dataURI.substring(base64Index);
  var raw = window.atob(base64);
  var rawLength = raw.length;
  var array = new Uint8Array(new ArrayBuffer(rawLength));

  for(i = 0; i < rawLength; i++) {
    array[i] = raw.charCodeAt(i);
  }
  return array;
}

Upvotes: -1

user2061057
user2061057

Reputation: 1022

I got this working by modifying my service like this:

return this.http.post(
    this.createUrl,
    JSON.stringify(data),
    {headers: this.headers, responseType: ResponseContentType.Blob});

Adding ResponseContentType.Blob made the content appear as a blob and it worked!

Upvotes: 2

Related Questions