2

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);
                }
            });
        }
    }
}
2
  • Have you tried downloading your file as blob? Commented Aug 21, 2018 at 6:28
  • @HamidAsghari Yes it didn't work neither :( Commented Aug 21, 2018 at 6:45

2 Answers 2

4

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.');
        }
    }
Sign up to request clarification or add additional context in comments.

Comments

2

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);
  }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.