Download .xls file using Angular: Unexpected token P in JSON at position 0 at JSON.parse (<anonymous>)
For Angular 8+
return this.http.get(endpoint, { responseType: 'blob'});
return this.http.post(endpoint, postParams, { responseType: 'blob'});
It is subtle but if you look at the docs you will notice http.post
and http.get
does not take a generic return type of <T>
when we set responseType: 'blob'
. So we don't need the <Blob>
part in http.get<Blob>
anymore. Which makes sense when you think about it since we are telling HttpClient the response is of type blob
with responseType: 'blob'
.
https://angular.io/api/common/http/HttpClient#post
If you need something besides 'blob' here are the other options available for responseType.
responseType: 'arraybuffer' | 'blob' | 'json' | 'text'
https://angular.io/api/common/http/HttpRequest#responseType
You can set the responseType
in the get-request directly like this:
return this.http.get(endpoint, { responseType: 'application/octet-stream'});
Edit June 2020 - in Angular 9 there are four response types supported: 'arraybuffer'|'blob'|'json'|'text'
. So 'application/octet-stream'
would need to be replaced with 'blob'
as @ryan-e pointed out in his answer.
More information is here in the docs.
Your content-type
header is only used for the request-header, it does not influence the response.
I resoloved the problem in Angular 9.1.4 by using responseType blob and setting type in BlobPropertyBag later, e.g. for Excel files:
return this.httpClient.get(url, {
responseType: 'blob',
params: queryParams
})
.pipe(
map((res: any) => {
const blob = new Blob([res], {type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'});
return blob;
})
);