Angular RxJS-如何监视HTTP Get请求(而不是文件)的进度

Angular RxJS-如何监视HTTP Get请求(而不是文件)的进度,angular,rxjs,angular-httpclient,Angular,Rxjs,Angular Httpclient,如何利用HTTPClient的progress事件以Get请求的百分比显示进度,而Get请求不一定是文件请求 当前,HTTPClient的进度事件在请求完成后激发。我希望在后端处理内容长度,并确定前端加载内容的百分比 我正在为网格加载大量行,需要在UI上显示增量进度。有可能吗?这个呢: import { HttpEventType, HttpClient, HttpRequest} from '@angular/common/http'; 你可以用这个 const req = new Htt

如何利用HTTPClient的
progress
事件以Get请求的百分比显示进度,而Get请求不一定是文件请求

当前,HTTPClient的
进度
事件在请求完成后激发。我希望在后端处理
内容长度
,并确定前端加载内容的百分比

我正在为网格加载大量行,需要在UI上显示增量进度。有可能吗?

这个呢:

import { HttpEventType, HttpClient, HttpRequest} from '@angular/common/http';

你可以用这个

const req = new HttpRequest('POST', '/upload/file', file, {
reportProgress: true
});
接下来,将此请求对象传递给HttpClient.request()方法,该方法返回可观察的HttpEvents,拦截器处理的相同事件:

// The `HttpClient.request` API produces a raw event stream
// which includes start (sent), progress, and response events.
return this.http.request(req).pipe(
map(event => this.getEventMessage(event, file)),
tap(message => this.showProgress(message)),
last(), // return last (completed) message to caller
catchError(this.handleError(file))
);
最后你可以用它来帮助我

/** Return distinct message for sent, upload progress, & response events */
private getEventMessage(event: HttpEvent<any>, file: File) {
switch (event.type) {
case HttpEventType.Sent:
  return `Uploading file "${file.name}" of size ${file.size}.`;

case HttpEventType.UploadProgress:
  // Compute and show the % done:
  const percentDone = Math.round(100 * event.loaded / event.total);
  return `File "${file.name}" is ${percentDone}% uploaded.`;

case HttpEventType.Response:
  return `File "${file.name}" was completely uploaded!`;

default:
  return `File "${file.name}" surprising upload event: ${event.type}.`;
  }
}
/**返回发送、上载进度和响应事件的不同消息*/
私有getEventMessage(事件:HttpEvent,文件:file){
开关(事件类型){
案例HttpEventType。已发送:
返回大小为${file.size}的`上载文件${file.name}';
案例HttpEventType.UploadProgress:
//计算并显示完成百分比:
const percentDone=Math.round(100*event.loaded/event.total);
return`File“${File.name}”已上载${percentDone}%;
案例HttpEventType。响应:
return`File“${File.name}”已完全上载!`;
违约:
返回`File“${File.name}”意外上载事件:${event.type}`;
}
}

我知道这个问题比较老,但我在寻找类似问题的答案时偶然发现了这个问题,因为没有公认的答案,所以我发布了我的解决方案

我最近实现了一种通用方法,无论angular 8中的类型如何,都可以为每个请求显示进度条

首先,我创建了一个
HttpInterceptor
,它将自动拦截
reportProgress
选项设置为
true
的每个http调用

@Injectable()
export class HttpProgressInterceptor implements HttpInterceptor {

  constructor(
    private spinnerService: SpinnerService // my personal service for the progress bar - replace with your own
  ) {}

  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    if (req.reportProgress) {
      // only intercept when the request is configured to report its progress
      return next.handle(req).pipe(
        tap((event: HttpEvent<any>) => {
          if (event.type === HttpEventType.DownloadProgress) {
            // here we get the updated progress values, call your service or what ever here
            this.spinnerService.updateGlobalProgress(Math.round(event.loaded / event.total * 100)); // display & update progress bar
          } else if (event.type === HttpEventType.Response) {
            this.spinnerService.updateGlobalProgress(null); // hide progress bar
          }
        }, error => {
          this.spinnerService.updateGlobalProgress(null); // hide progress bar
        })
      );
    } else {
      return next.handle(req);
    }
  }
}
基本上我们已经完成了,唯一剩下的就是我们需要改变调用API的方式。如果希望使用此拦截器监视特定请求,则需要通知angular报告HttpRequest的进度:

@Injectable()
export class MyService {

  constructor(
    private http: HttpClient
  ) {}

  myGetMethod() {
    const url = "api/data/load/big/data";
    const req = new HttpRequest("GET", url, {
      reportProgress: true  // this is important!
    });

    return this.http.request(req);
  }
}
这种调用
httpClient
api的方法在调用
时会传递一个不同的对象。subscribe
因此,在调用
myGetMethod()
时,我们需要注意这一点:

ngOnInit(){
this.myService.myGetMethod().subscribe((事件:HttpEvent)=>{
if(event.type==HttpEventType.Response){
const responseData=事件主体;
console.dir(responseData);//对响应执行一些操作
}
});
}
我们也可以在这里监听
HttpEventType.DownloadProgress
事件并更新此组件中的进度值,但这不是我示例的重点

提示:如果遇到未定义
event.total
的问题-必须检查REST后端是否真的提供了
内容长度
标题-如果缺少此标题,您将无法计算进度


无论如何,我希望有一天这会对某人有所帮助,在请求完成后,三个
控制台.log
只打印一次<代码>已加载,总计:4个未定义的
进度:NaN
响应:null
您使用的是什么角度版本?我使用的是
4.4.3
。我不明白您打印的值?是否完全为空?如果标头在浏览器的网络中不可见,则服务器不会发送它。不同的问题,不同的问题;-)它写为“非文件”,我还在
reportProgress:true
附近添加了以下选项:
observe:“events”
-这使得进度条更频繁地刷新
@NgModule({
  declarations: [
    AppComponent,
    ...
  ],
  imports: [
    BrowserModule,
    ...
    RouterModule.forRoot(appRoutes)
  ],
  providers: [
    ...
    { provide: HTTP_INTERCEPTORS, useClass: HttpProgressInterceptor, multi: true },
    ...}
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }
@Injectable()
export class MyService {

  constructor(
    private http: HttpClient
  ) {}

  myGetMethod() {
    const url = "api/data/load/big/data";
    const req = new HttpRequest("GET", url, {
      reportProgress: true  // this is important!
    });

    return this.http.request(req);
  }
}
ngOnInit() {
  this.myService.myGetMethod().subscribe((event: HttpEvent<any>) => {
    if (event.type === HttpEventType.Response) {
      const responseData = event.body;
      console.dir(responseData); // do something with the response
    }
  });
}