javascript - ändern - Fortschrittsanzeige für Abruf hochladen?




js document methods (6)

Da keine der Antworten das Problem löst.

Um die Implementierung zu vereinfachen, können Sie die Upload-Geschwindigkeit mit einem kleinen Anfangsblock bekannter Größe ermitteln und die Upload-Zeit kann mit der Länge des Inhalts / der Upload-Geschwindigkeit berechnet werden. Sie können diese Zeit als Schätzung verwenden.

Ich habe Probleme, Dokumentation oder Beispiele für die Implementierung einer Upload-Fortschrittsanzeige mithilfe von fetch .

Dies ist die einzige Referenz, die ich bisher gefunden habe und die besagt:

Fortschrittsereignisse sind eine High-Level-Funktion, die derzeit nicht abgerufen werden kann. Sie können Ihre eigenen erstellen, indem Sie sich den Content-Length Header ansehen und einen Pass-Through-Stream verwenden, um die empfangenen Bytes zu überwachen.

Das heißt, Sie können Antworten ohne Content-Length explizit unterschiedlich behandeln. Und natürlich kann es eine Lüge sein, auch wenn Content-Length ist. Mit Streams können Sie mit diesen Lügen umgehen, wie Sie möchten.

Wie würde ich einen "Pass-Through-Stream zur Überwachung der Bytes" senden? Wenn es einen Unterschied macht, versuche ich dies, um das Hochladen von Bildern vom Browser nach Cloudinary .

HINWEIS : Ich interessiere mich nicht für die Cloudinary JS-Bibliothek , da dies von jQuery abhängt und meine App dies nicht tut. Ich bin nur an der Stream-Verarbeitung interessiert, die erforderlich ist, um dies mit nativem Javascript und Github's fetch Polyfill zu tun.

https://fetch.spec.whatwg.org/#fetch-api



Ich denke nicht, dass es möglich ist. In dem Entwurf heißt es:

Es fehlt derzeit [ im Vergleich zu XHR ], wenn es darum geht, den Fortschritt anzufordern

(alte Antwort):
Das erste Beispiel im https://fetch.spec.whatwg.org/#fetch-api gibt einen Einblick in die folgenden https://fetch.spec.whatwg.org/#fetch-api :

Wenn Sie die Körperdaten nach und nach erhalten möchten:

function consume(reader) {
  var total = 0
  return new Promise((resolve, reject) => {
    function pump() {
      reader.read().then(({done, value}) => {
        if (done) {
          resolve()
          return
        }
        total += value.byteLength
        log(`received ${value.byteLength} bytes (${total} bytes in total)`)
        pump()
      }).catch(reject)
    }
    pump()
  })
}

fetch("/music/pk/altes-kamuffel.flac")
  .then(res => consume(res.body.getReader()))
  .then(() => log("consumed the entire body without keeping the whole thing in memory!"))
  .catch(e => log("something went wrong: " + e))

Abgesehen von der Verwendung des Promise Konstruktor-Antipatterns können Sie sehen, dass response.body ein Stream ist, aus dem Sie mit einem Reader Byte für Byte lesen und ein Ereignis response.body oder eine beliebige Aktion ausführen können (z. B. den Fortschritt protokollieren) jeder von ihnen.

Die Streams-Spezifikation scheint jedoch nicht ganz fertig zu sein, und ich habe keine Ahnung, ob dies bereits in einer Abrufimplementierung funktioniert.


Meine Lösung ist die Verwendung von axios , was dies ziemlich gut unterstützt:

      axios.request( {
        method: "post", 
        url: "/aaa", 
        data: myData, 
        onUploadProgress: (p) => {
          console.log(p); 
          //this.setState({
            //fileprogress: p.loaded / p.total
          //})
        }


      }).then (data => {
        //this.setState({
          //fileprogress: 1.0,
        //})
      })

Ich habe ein Beispiel dafür, wie man dies in "Reagieren auf github.


const req = await fetch('./foo.json');
const total = Number(req.headers.get('content-length'));
let loaded = 0;
for await(const {length} of req.body.getReader()) {
  loaded = += length;
  const progress = ((loaded / total) * 100).toFixed(2); // toFixed(2) means two digits after floating point
  console.log(`${progress}%`); // or yourDiv.textContent = `${progress}%`;
}

const response = await fetch(url);
const total = Number(response.headers.get('content-length'));

const reader = response.body.getReader();
let bytesReceived = 0;
while (true) {
    const result = await reader.read();
    if (result.done) {
        console.log('Fetch complete');
        break;
    }
    bytesReceived += result.value.length;
    console.log('Received', bytesReceived, 'bytes of data so far');
}

Dank diesem Link: https://jakearchibald.com/2016/streams-ftw/







fetch-api