hofshteyn
hofshteyn

Reputation: 1272

Angular 6: downloading file issue

I faced with a problem and I can't find any solution for it. So I apologize in advance if this question somehow duplicates someone else.

The problem is I'm sending GET request to backend and have a response. There is Blob inside responses body. I trying to download it but before I'm getting a filename to name my downloading file. And locally everything works good. But in external version file won't downloading. I have response after clicking on a button and I saw that I went into the save function in FileUtil. But downloading doesn't start. Could anybody knows whats the problem is?

Here is the response in Network tab in Chrome inspect tool (as you can see all headers are receiving) enter image description here

download.service.ts

downloadFile(id: string) {
    return this.apiService.getFile(id).pipe(
        map(response => {
            const data = response.body;
            const blob = new Blob([data], { type: 'application/zip' });
            FileUtil.save(blob, this.getFileName(response.headers));
        })
    )
}

private getFileName(headers: HttpHeaders) {
    const contentDisposition = headers.get('Content-Disposition') || '';
    const matches = /filename=([^;]+)/ig.exec(contentDisposition);
    const fileName = (matches[1] || 'file.zip').trim();
    return fileName;
}

api.service.ts

getFile(id: string): Observable<HttpResponse<Blob>> {
    return this.httpClient.get<Blob>(requestUrl, {responseType: 'blob' as 'json', observe: 'response'});
}

FileUtil.ts

static save(data: Blob, name: string) {
    const a = document.createElement('a');
    document.body.appendChild(a);
    const url = window.URL.createObjectURL(data);
    a.href = url;
    const filename = name;
    a.download = filename;
    a.click();
    setTimeout(() => {
        window.URL.revokeObjectURL(url);
        document.body.removeChild(a);
    }, 0);
}

Upvotes: 4

Views: 5062

Answers (2)

hofshteyn
hofshteyn

Reputation: 1272

The reason of problem was missing ('Access-Control-Expose-Headers', 'Content-Disposition') and browser didn't know that my response was the attachment that he should download. So check the headers of your response twice.

Upvotes: 1

Yash Rami
Yash Rami

Reputation: 2327

you can try like this

FileUtil.ts

 save(data: Blob, name: string) {
   const a = document.createElement('a');
   document.body.appendChild(a);
   const blob = new Blob([data], { type: 'octet/stream' });
   const url = window.URL.createObjectURL(data);
   a.href = url;
   a.download = "filename.csv"; // you need to write the extension of file here
   a.click();
   window.URL.revokeObjectURL(url);
  })
 }

Upvotes: 0

Related Questions