Start · Sprachen · JavaScript · Referenz · ProgressEvent.total

ProgressEvent.total

Eigenschaft

Schreibgeschützte Zahl, die die Gesamtgröße der zu übertragenden oder zu verarbeitenden Daten angibt, meist in Bytes. Wenn die Größe unbekannt ist, steht hier <code>0</code>.

seit JavaScript Baseline: alle Browser Kategorie: webapi

Signatur

ProgressEvent.total

Beschreibung

ProgressEvent.total gibt an, wie groß die Datenmenge ist, die insgesamt übertragen oder verarbeitet werden soll. Bei HTTP-Übertragungen mit XMLHttpRequest sind das Bytes. Beim Download entspricht der Wert in der Regel dem Content-Length-Header der Antwort, beim Upload der Größe des gesendeten Request-Bodys. Beim FileReader ist es die Größe der gelesenen Datei bzw. des Blob.

Zusammen mit ProgressEvent.loaded lässt sich ein Fortschritt in Prozent berechnen, etwa für Fortschrittsbalken oder Statusanzeigen. Ob total überhaupt aussagekräftig ist, zeigt die Eigenschaft ProgressEvent.lengthComputable. Ist sie false, steht in total der Wert 0. Dann ist keine Prozentangabe möglich, und Sie sollten stattdessen eine unbestimmte Fortschrittsanzeige verwenden.

Die Eigenschaft ist schreibgeschützt. Eigene ProgressEvent-Objekte können Sie aber über den Konstruktor mit einem beliebigen total-Wert erzeugen, zum Beispiel für eigene Fortschrittsmeldungen in Bibliotheken oder für Tests.

Rückgabewert

Typ
number
Beschreibung
Gesamtgröße der Daten als nicht-negative Zahl, bei HTTP und Dateien in Bytes. Der Wert ist 0, wenn die Größe unbekannt ist (lengthComputable === false).

Beispiele

Download-Fortschritt mit XMLHttpRequest anzeigen

const xhr = new XMLHttpRequest();
xhr.open('GET', '/dateien/bericht.pdf');
xhr.responseType = 'blob';

xhr.addEventListener('progress', (event) => {
  if (event.lengthComputable) {
    const prozent = Math.round((event.loaded / event.total) * 100);
    console.log(`${event.loaded} von ${event.total} Bytes (${prozent} %)`);
  } else {
    // Gesamtgröße unbekannt, z. B. fehlender Content-Length-Header
    console.log(`${event.loaded} Bytes geladen (Gesamtgröße unbekannt)`);
  }
});

xhr.send();
524288 von 2097152 Bytes (25 %) 1048576 von 2097152 Bytes (50 %) 2097152 von 2097152 Bytes (100 %)

Upload-Fortschritt in ein <progress>-Element schreiben

const input = document.querySelector('#datei');
const balken = document.querySelector('progress');

input.addEventListener('change', () => {
  const formData = new FormData();
  formData.append('datei', input.files[0]);

  const xhr = new XMLHttpRequest();
  xhr.open('POST', '/api/upload');

  // Upload-Events hängen an xhr.upload, nicht an xhr selbst
  xhr.upload.onprogress = (event) => {
    if (event.lengthComputable) {
      balken.max = event.total;
      balken.value = event.loaded;
    } else {
      balken.removeAttribute('value'); // unbestimmter Zustand
    }
  };

  xhr.send(formData);
});

Datei einlesen mit FileReader

const input = document.querySelector('input[type=file]');

input.addEventListener('change', () => {
  const reader = new FileReader();

  reader.onprogress = (event) => {
    console.log(`Gelesen: ${event.loaded} / ${event.total} Bytes`);
  };
  reader.onload = (event) => {
    console.log('Fertig, Gesamtgröße:', event.total);
  };

  reader.readAsArrayBuffer(input.files[0]);
});
Gelesen: 8388608 / 15000000 Bytes Fertig, Gesamtgröße: 15000000

Eigenes ProgressEvent erzeugen

const event = new ProgressEvent('progress', {
  lengthComputable: true,
  loaded: 30,
  total: 120
});

console.log(event.total);                     // 120
console.log(event.loaded / event.total);      // 0.25

event.total = 999; // wird ignoriert, schreibgeschützt
console.log(event.total);
120 0.25 120

// Wichtig · Fallstricke

  • Immer lengthComputable prüfen: Ist die Größe unbekannt, liefert total den Wert 0. Die Rechnung loaded / total ergibt dann Infinity bzw. NaN.
  • Komprimierte Antworten: Bei Content-Encoding: gzip oder br bezieht sich Content-Length auf die komprimierten Bytes. loaded zählt aber je nach Browser die entpackten Bytes. Dadurch kann loaded größer werden als total, und die Prozentangabe steigt über 100 %. Begrenzen Sie den Wert zur Sicherheit mit Math.min(1, loaded / total).
  • CORS: Bei Anfragen an andere Ursprünge muss der Server Content-Length senden. Außerdem darf der Header nicht durch Chunked Transfer Encoding fehlen. Fehlt die Angabe, ist lengthComputable gleich false. Upload-Events auf xhr.upload lösen bei Cross-Origin-Anfragen einen Preflight aus.
  • Fetch-API: fetch() löst keine ProgressEvents aus. Dort lesen Sie response.headers.get('Content-Length') und zählen die Bytes selbst über response.body.getReader().
  • Laut Spezifikation ist der Typ unsigned long long. Für Werte über 253 Bytes gibt es in der Praxis also kaum Genauigkeitsprobleme.
  • Die Eigenschaft wird in allen modernen Browsern unterstützt, außerdem in Web Workern.