2

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

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

其次,进度值总是从 100% 开始,并且开始递增。

我正在懒惰地加载我的模块,HttpInterceptor 在 app.module 级别注册。

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

我的HttpInterceptor服务看起来像,

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

我的 Http 调用者服务,

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

我试图取得进展的方法是,

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

进步行为是,

在此处输入图像描述

4

1 回答 1

2

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

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

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

还引用了该文件:

// HttpClient.requestAPI 产生一个原始事件流

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

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

于 2018-07-02T08:09:09.907 回答