Reputation: 564
In our Angular5 webapp we call an API to get a zip archive (Backend is ASP.NET Core 2.1 using SharpZipLib). It worked fine using the old HTTP API of Angular :)
But since we upgraded to the new HttpClient API (to handle XSRF using HttpInterceptor), the download now failed without explanations (response of the API is 200 OK)
Here's the actual code:
public getCsvArchive(url: string) {
const headers = new HttpHeaders({ 'responseType': 'arraybuffer' });
return this._http.get(url, { headers } )
.timeout(ServiceConfigurator.TIMEOUT)
.catch(this.handleError);
}
For some reasons if I put directly the "responseType: arraybuffer" into the get method, the download works....but the size of the retrieved file is not what we expected (the archive doesn't even open)
Maybe be the interceptor is the culprit ?
@Injectable()
export class RequestInterceptor implements HttpInterceptor {
private getTokenName = 'XSRF-TOKEN';
private setTokenName = 'X-XSRF-TOKEN';
private tokenValue: string;
constructor(private _cookieService: CookieService) { }
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
let headers = new HttpHeaders({
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*',
'Cache-Control': 'no-cache',
'if-none-match': 'no-match-for-this',
'Pragma': 'no-cache'
});
if (req.method !== 'GET') {
if (this.tokenValue) {
headers = headers.append(this.setTokenName, this.tokenValue);
}
return next.handle(req.clone({ headers }));
} else {
return next.handle(req.clone({ headers })).do((ev: HttpEvent<any>) => {
if (ev instanceof HttpResponse) {
if (environment.use_dp) {
console.log(this._cookieService.get(this.getTokenName));
this.tokenValue = this._cookieService.get(this.getTokenName);
}
this._cookieService.put(this.getTokenName, this.tokenValue);
}
});
}
}
}
Upvotes: 2
Views: 8635
Reputation: 564
All right I found out what was the problem but I forgot to include another piece of code so I'm going to take UnluckyAj response as an example because it's very similar ;)
Here's what I had before moving to HttpClient new API
getFile() {
this.fileService.getFile('url', this.type).subscribe(respData => {
this.downloadFile(respData._body, this.type);
}, error => {
console.log(error);
});
}
At this time 'respData' is a special object which had a property called '_body' that contains the whole content I'm interested in :)
But after moving to HttpClient, 'respData' was already a 'Blob' and didn't have the '_body' property as before. So by changing the code to this one which is the same as UnluckyAj (+1):
getFile() {
this.fileService.getFile('url', this.type).subscribe(respData => {
this.downloadFile(respData., this.type);
}, error => {
console.log(error);
});
}
It now works :) But in downloadFile method I use FileSaver library as our webapp is not a Progressive WebApp ;)
downloadFile(data: any) {
const blob = new Blob([data], { type: 'application/zip' });
const fileName = 'CSV_CONTENT.ZIP';
FileSaver.saveAs(blob, fileName);
}
Upvotes: 2
Reputation: 7231
Try something like this:
Using blob:
service call:
this.type = 'application/zip'
getFile(url:string,type:string){
let headers = new HttpHeaders().append("Authorization", "Bearer " + token)
return this.httpClient.get(url, {responseType: 'arraybuffer',headers:headers});
}
component:
get file from server:
getFile() {
this.fileService.getFile('url, this.type).subscribe(respData => {
this.downLoadFile(respData, this.type);
}, error => {
console.log(error);
});
}
download file:
* Method is use to download file.
* @param data - Array Buffer data
* @param type - type of the document.
*/
downLoadFile(data: any, type: string) {
var blob = new Blob([data], { type: type.toString() });
var url = window.URL.createObjectURL(blob);
var pwa = window.open(url);
if (!pwa || pwa.closed || typeof pwa.closed == 'undefined') {
alert('Please disable your Pop-up blocker and try again.');
}
}
Upvotes: 4