如何使用angular2 http API跟踪上传/下载进度

时间:2017-02-14 16:19:11

标签: http angular interceptor angular2-http

有很多adhoc库支持angular2的上传/下载进度,我不知道如何使用native angular2 http api在上传/下载时显示进度。

我想使用原生http api的原因是因为我想利用

  1. 本地http api周围的http拦截器(http API包装器),验证,缓存和扩展丰富了发送的实际http请求,例如this& this
  2. 除了angular的http api比任何adhoc API更强大
  3. 关于如何使用angular的http api

    进行上传/下载有this nice article

    但文章提到没有本地方式来支持进步。

    有没有人尝试使用http api来显示进度?

    如果没有,你知道角度回购中的问题吗?

3 个答案:

答案 0 :(得分:39)

从Angular 4.3.x及更高版本开始,可以使用@angular/common/http中的新HttpClient来实现。

阅读Listening to progress events部分。

简单上传示例(从上述部分复制):

const req = new HttpRequest('POST', '/upload/file', file, {
  reportProgress: true,
});

http.request(req).subscribe(event => {
  // Via this API, you get access to the raw event stream.
  // Look for upload progress events.
  if (event.type === HttpEventType.UploadProgress) {
    // This is an upload progress event. Compute and show the % done:
    const percentDone = Math.round(100 * event.loaded / event.total);
    console.log(`File is ${percentDone}% uploaded.`);
  } else if (event instanceof HttpResponse) {
    console.log('File is completely uploaded!');
  }
});

对于下载,它可能是几乎相同的东西:

const req = new HttpRequest('GET', '/download/file', {
  reportProgress: true,
});

http.request(req).subscribe(event => {
  // Via this API, you get access to the raw event stream.
  // Look for download progress events.
  if (event.type === HttpEventType.DownloadProgress) {
    // This is an download progress event. Compute and show the % done:
    const percentDone = Math.round(100 * event.loaded / event.total);
    console.log(`File is ${percentDone}% downloaded.`);
  } else if (event instanceof HttpResponse) {
    console.log('File is completely downloaded!');
  }
});

请记住,如果您正在监控下载,则必须设置Content-Length,否则无法测量请求。

答案 1 :(得分:3)

我建议使用包裹为Observable的原生JavaScript XHR,它可以很容易地自己创建:

upload(file: File): Observable<string | number> {

    let fd: FormData = new FormData();

    fd.append("file", file);

    let xhr = new XMLHttpRequest;

    return Observable.create(observer => {

        xhr.addEventListener("progress", (progress) => {

            let percentCompleted;

            // Checks if we can really track the progress
            if (progress.lengthComputable) {

                // progress.loaded is a number between 0 and 1, so we'll multiple it by 100
                percentCompleted = Math.round(progress.loaded / progress.total * 100);

                if (percentCompleted < 1) {
                    observer.next(0);
                } else {
                    // Emit the progress percentage
                    observer.next(percentCompleted);
                }
            }
        });

        xhr.addEventListener("load", (e) => {

            if (e.target['status'] !== 200) observer.error(e.target['responseText']);

            else observer.complete(e.target['responseText']);
        });

        xhr.addEventListener("error", (err) => {

            console.log('upload error', err);

            observer.error('Upload error');
        });

        xhr.addEventListener("abort", (abort) => {

            console.log('upload abort', abort);

            observer.error('Transfer aborted by the user');
        });

        xhr.open('POST', 'http://some-dummy-url.com/v1/media/files');

        // Add any headers if necessary
        xhr.setRequestHeader("Authorization", `Bearer rqrwrewrqe`);

        // Send off the file
        xhr.send(fd);

        // This function will get executed once the subscription
        // has been unsubscribed
        return () => xhr.abort()
    });
}

这就是人们如何使用它:

// file is an instance of File that you need to retrieve from input[type="file"] element
const uploadSubscription = this.upload(file).subscribe(progress => {
    if (typeof progress === Number) {
        console.log("upload progress:", progress);
    }
});

// To abort the upload
// we should check whether the subscription is still active
if (uploadSubscription) uploadSubscription.unsubscribe();

答案 2 :(得分:0)

现在可以了,请查看https://angular.io/guide/http#tracking-and-showing-request-progress

我可以在这里举个例子,但我认为 Angular 文档中的官方例子会更好