可以在HttpInterceptor中获取上传进度事件,但不能从HttpClient调用中获取吗?

时间:2018-07-02 03:48:03

标签: angular file-upload upload angular-httpclient angular-httpclient-interceptors

我正在使用HttpInterceptor,并且我有一个Http服务,该服务调用运行HttpClient的http方法。我正在尝试获取上传进度,我在这里面临两个问题,

首先,进度事件仅被HttpInterceptor捕获,而不是服务中的任何Http调用者方法。看起来前者掩盖了进度报告。

第二,进度值始终以100%开头,并开始递增。

我正在延迟加载我的模块,HttpInterceptor在app.module级别注册。

如何从http方法获取进度值?

我的if (req.url.search('https') < 0) { const headers = new HttpHeaders({ Accept: 'application/json', Authorization: `Bearer ${this.authService.getToken()}`, 'X-XSRF-TOKEN': `${this.authService.getAntiforgeryToken()}`, ClientTimeZoneOffest: `${new Date().getTimezoneOffset()}`, ClientTimeZoneId: Intl.DateTimeFormat().resolvedOptions().timeZone, ClinetLogInId: `${this.authService.getLogInId()}`, }); const cloneReq = req.clone({ headers }); return next.handle(cloneReq).pipe( mergeMap((ev: HttpEvent<any>) => { if (ev.type === HttpEventType.UploadProgress) { const percentDone = Math.round((100 * ev.loaded) / ev.total); console.log(`File is ${percentDone}% uploaded.`); } this.httpResponseHandlerService.handleSuccessResponse(ev); return Observable.of(ev); }), catchError(error => { this.httpResponseHandlerService.handleErrorResponse(error, req); return Observable.throw(error); }), ); } else { return next.handle(req); } } 服务看起来像

public upload<T>(apiUrl: string, jsonData: {} = {}) {
    return this.httpService.post<T>(this.baseUrl + apiUrl, jsonData, {
      reportProgress: true,
    });
  }

我的Http呼叫者服务

this.httpService
        .upload(this.api + this.id.value, data)
        .takeUntil(this.unsubscribe)
        .subscribe((ev: HttpEvent<any>) => { // Nothing is happening here!
          if (ev.type === HttpEventType.UploadProgress) {
            const percentDone = Math.round((100 * ev.loaded) / ev.total);
            console.log(`File is ${percentDone}% uploaded.`);
          }
        });

我试图获得进展的方法就像

{{1}}

进度行为是

enter image description here

1 个答案:

答案 0 :(得分:2)

您执行请求的方式不正确,请参阅http://angular.io/guide/http#listening-to-progress-events

您应该创建一个HttpRequest,然后调用this.http.request(req)而不是this.http.post(...)

http.post只是http.request执行正常http请求的简写。对于完整的请求创建选项,例如当我们要通过进度跟踪下载或上传时,应使用http.request(在其中手动创建带有许多选项的请求对象,然后执行)。

也引用了该文件:

  

// HttpClient.request API产生原始事件流

     

//,其中包括开始(发送),进度和响应事件。

顺便说一句,将上传进度处理放在HttpInterceptor中不是一个好习惯,因为它的效果是整个项目范围内的,即您提出的每个请求都将通过拦截器。而且您不需要在每个请求中都进行进度处理吗?