代码之家  ›  专栏  ›  技术社区  ›  moueidat

Angular-使用HttpClientAPI下载zip存档失败

  •  1
  • moueidat  · 技术社区  · 7 年前

    在我们的Angular5 webapp中,我们调用一个API来获取一个zip存档(后端是使用SharpZipLib的ASP.NET Core 2.1)。它使用Angular:的旧HTTP API运行良好)

    但由于我们升级到了新的HttpClient API(使用HttpInterceptor处理XSRF),下载现在失败了,没有任何解释(API的响应是200ok)

    下面是实际代码:

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

    可能是拦截器是罪魁祸首?

    @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 回复  |  直到 7 年前
        1
  •  3
  •   Akj    7 年前

    试试这样的:

    使用 :

    this.type='应用程序/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.');
            }
        }
    
        2
  •  0
  •   moueidat    7 年前

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

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

    此时'respData'是一个特殊的对象,它有一个名为'u body'的属性,包含我感兴趣的全部内容:)

    但在迁移到HttpClient之后,“respData”已经是一个“Blob”,并且不像以前那样具有“cubody”属性。因此,将代码更改为与UnluckyAj相同的代码(+1):

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

    现在可以工作了:)但是在downloadFile方法中,我使用FileSaver库,因为我们的webapp不是一个渐进的webapp;)

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