Reputation: 620
I spent lot a lot of time to find a solution using 'file-saver' angular module to handle a file download from my apache server.
In the front-end, the method used to download is :
public download(document: any): void {
const headers = new HttpHeaders();
headers.append('Accept', 'application/octet-stream, */*');
this.api.download(document.id, headers).subscribe((response) => {
this._save(response);
});
}
The 'api' do the following :
public download(id: number, headers: HttpHeaders): Observable<any> {
return this.http.get<any>(
Constants._ICE_API_ROOT + 'Download/' + id,
{ headers }
);
}
When i run the Angular App and check the console, get HttpErrorResponse :
HttpErrorResponse {headers: HttpHeaders, status: 200, statusText: "OK", url: "http://crmapi.wrk/Download/2", ok: false, …}
SyntaxError: Unexpected token P in JSON at position 0 at JSON.parse (<anonymous>)
And it seems to be correct as the content returned by the server is the content of the file i want to download...
At the backend side, the PHP code is simple :
$path = $document->folder . $document->name;
if (array_key_exists("HTTP_ACCESS_CONTROL_REQUEST_HEADERS", $_SERVER)) {
header("Access-Control-Allow-Headers: " . $_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS'] . "," . $document->type);
} else {
header("Access-Control-Allow-Headers: " . $document->type);
}
header("Content-Disposition: attachment; filename=" . $document->name);
header("Content-Type: " . $document->type);
header("Content-Transfer-Encoding: Binary");
header("Content-Length:". $document->size);
readfile($path);
exit();
So my questions :
Thx
Upvotes: 0
Views: 1619
Reputation: 620
Finally, and according to @AshishRanjan solutions, i update my code this way :
component code :
public download(document: any): void {
const headers = new HttpHeaders();
headers.append('Accept', document.type);
this.api.download(document.id, headers).subscribe((response) => {
this._save(response, document);
});
}
private _save(rawDocument: Blob, document: any): void {
saveAs(rawDocument, document.name);
}
API :
public download(id: number, headers: HttpHeaders): Observable<any> {
return this.http.get(
Constants._ICE_API_ROOT + 'Download/' + id,
{ headers: headers, responseType: 'blob' as 'blob' }
);
}
Upvotes: 0
Reputation: 12960
Please use {responseType: ResponseContentType.Blob}
in RequestOptions while sending the request. Import ResponseContentType
from @angular/http
.
And hopefully through this._save()
you are using filesaver's
saveAs()
. Although it shouldn't be a problem but try using with this._save(response.blob())
HttpClient
, I don't think there is any ResponseContentType
, I believe what will work for you will be: {responseType: 'blob'}
or {responseType: 'text'}
try either.
You don't have to set this as a header in the request, responseType
is part of RequestOptions
as pointed out in a comment below.. Have a look at this: https://angular.io/api/common/http/HttpClient#get
So, basically your request will look something like:
this.http.get<any>(url, { headers: yourHeaders, responseType: 'blob'});
Upvotes: 1