web-dev-qa-db-fra.com

Comment utiliser l'API http angular2 pour suivre la progression du téléchargement / téléchargement

Bien qu'il existe de nombreuses bibliothèques adhoc prenant en charge la progression du téléchargement/téléchargement dans angular2, je ne sais pas comment utiliser l'api http angular2 native pour afficher la progression lors du téléchargement/téléchargement.

La raison pour laquelle je veux utiliser l'api http natif est parce que je veux utiliser

  1. intercepteurs http (wrappers API HTTP) autour de l'API http native qui valident, mettent en cache et enrichissent la demande HTTP réelle envoyée, comme this & this
  2. En outre, l'API http angulaire est beaucoup plus robuste que toutes les API adhoc

Il y a cet article de Nice sur la façon de télécharger/télécharger en utilisant l'API http angular

Mais l'article mentionne qu'il n'y a aucun moyen natif de soutenir le progrès.

Quelqu'un a-t-il essayé d'utiliser l'API http pour afficher les progrès?

Sinon, connaissez-vous un problème dans le repo angular pour cela?

18
Ashok Koyi

À partir de Angular 4.3.x et au-delà des versions , cela peut être réalisé en utilisant le nouveau HttpClient de @angular/common/http.

Lisez la section Écoute des événements de progression .

Exemple de téléchargement simple (copié de la section mentionnée ci-dessus):

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

Et pour le téléchargement, cela pourrait être à peu près la même chose:

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

N'oubliez pas que si vous surveillez un téléchargement, le Content-Length doit être défini, sinon, il n'y a aucun moyen de mesurer la demande.

40
Edmundo Rodrigues

Je suggérerais d'utiliser le JavaScript natif XHR encapsulé comme observable, il est assez facile de créer vous-même:

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

Et voici comment on pourrait l'utiliser:

// 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();
3
borislemke