Angular-使用HttpClient API下载zip存档失败

时间:2018-08-21 06:23:03

标签: angular angular-httpclient

在Angular5网络应用程序中,我们调用API来获取zip存档(后端是使用SharpZipLib的ASP.NET Core 2.1)。使用Angular的旧HTTP API可以正常工作:)

但是,由于我们升级到了新的HttpClient API(使用HttpInterceptor处理XSRF),因此下载失败了,没有任何说明(API的响应为200 OK)

这是实际的代码:

  public getCsvArchive(url: string) {
    const headers = new HttpHeaders({ 'responseType': 'arraybuffer' });
    return this._http.get(url, { headers } )
      .timeout(ServiceConfigurator.TIMEOUT)
      .catch(this.handleError);
  }

由于某些原因,如果我直接将“ responseType:arraybuffer”放入get方法中,则下载工作正常。...但是检索到的文件大小不是我们期望的(档案甚至无法打开)< / p>

也许是拦截者是罪魁祸首?

@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 个答案:

答案 0 :(得分:2)

尝试这样的事情:

使用斑点

服务电话:

  

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

组件:

从服务器获取文件:

getFile() {
        this.fileService.getFile('url, this.type).subscribe(respData => {
            this.downLoadFile(respData, this.type);
        }, error => {
           console.log(error);
        });
    }

下载文件:

     * 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.');
        }
    }

答案 1 :(得分:0)

好的,我发现了问题所在,但是我忘了包含另一段代码,因此我将以UnluckyAj响应为例,因为它非常相似;)

这就是我转向HttpClient新API之前的情况

getFile() {
        this.fileService.getFile('url', this.type).subscribe(respData => {
            this.downloadFile(respData._body, this.type);
        }, error => {
           console.log(error);
        });
    }

这时'respData'是一个特殊的对象,具有一个名为'_body'的属性,其中包含我感兴趣的全部内容:)

但是在转到HttpClient之后,“ respData”已经是“ Blob”,并且没有像以前一样的“ _body”属性。因此,通过将代码更改为与UnluckyAj(+1)相同的代码:

getFile() {
        this.fileService.getFile('url', this.type).subscribe(respData => {
            this.downloadFile(respData., this.type);
        }, error => {
           console.log(error);
        });
    }

它现在可以工作了:),但是在downloadFile方法中,我使用FileSaver库,因为我们的Web应用程序不是渐进式WebApp;)

  downloadFile(data: any) {
    const blob = new Blob([data], { type: 'application/zip' });
    const fileName = 'CSV_CONTENT.ZIP';
    FileSaver.saveAs(blob, fileName);
  }