Obwohl es in angle2 viele Ad-hoc-Bibliotheken gibt, die den Upload/Download-Fortschritt unterstützen, weiß ich nicht, wie ich den Fortschritt beim Upload/Download mit der nativen Angular2-http-API anzeigen kann.
Der Grund, warum ich native http-API verwenden möchte, ist, weil ich verwenden möchte
Es gibt dieser nette Artikel wie man einen Upload/Download mit der http-API von angle macht
Der Artikel erwähnt jedoch, dass es keinen nativen Weg gibt, den Fortschritt zu unterstützen.
Hat jemand versucht, mit http api den Fortschritt anzuzeigen?
Wenn nicht, kennen Sie ein Problem im angular Repo dafür?
Ab den Versionen Angular 4.3.x und höher kann dies mit dem neuen HttpClient erreicht werden von @angular/common/http
.
Lesen Sie den Abschnitt Fortschrittsereignisse abhören .
Einfaches Upload-Beispiel (kopiert aus dem oben genannten Abschnitt):
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!');
}
});
Und zum Herunterladen könnte es ungefähr so sein:
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!');
}
});
Denken Sie daran, dass für den Fall, dass Sie einen Download überwachen, das Content-Length
muss gesetzt sein, sonst kann die Anforderung nicht gemessen werden.
Ich würde vorschlagen, dass Sie das native JavaScript XHR verwenden, das als Observable verpackt ist. Es ist ziemlich einfach, es selbst zu erstellen:
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()
});
}
Und so würde man es benutzen:
// 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();