Coder Perfect

Is it possible to upload progress indicators for fetch?

Problem

I’m having trouble finding documentation or examples of how to use fetch to construct an upload progress indication.

So far, this is the only reference I’ve located that says:

How would I go about writing “a pass-through stream to monitor the bytes” that were sent? I’m trying to do this to power image uploads from the browser to Cloudinary, if that makes any difference.

NOTE: The Cloudinary JS library is not for me because it requires jQuery, which my app does not. Only the stream processing required to execute this using native javascript and Github’s fetch polyfill is of interest to me.

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

Asked by neezer

Solution #1

The online platform is starting to get streams (https://jakearchibald.com/2016/streams-ftw/), but it’s still early.

Soon, you’ll be able to send a stream as the body of a request, although it’s unclear whether the stream’s consumption is related to the amount of data sent.

Data can be retransmitted to a different destination as a result of some redirection, but streams cannot “restart.” We can fix this by making the body a callback that can be called numerous times, but we need to make sure that revealing the number of redirects isn’t a security risk, as this would be the first time on the platform that JS could detect it.

Some argue that linking stream consumption to bytes uploaded isn’t even necessary.

To cut a long story short, this isn’t possible right now, but it will be in the future, either via streams or a higher-level callback passed into fetch ().

Answered by JaffaTheCake

Solution #2

My option is to utilize axios, which has a lot of support for this:

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,
    //})
})

On github, I have an example of how to use this with react.

Answered by dwjohnston

Solution #3

It’s now impossible, according to the accepted explanation. However, for a while, the code below solved our problem. I should mention that we had to move to an XMLHttpRequest-based library at the very least.

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

Thanks to https://jakearchibald.com/2016/streams-ftw/ for the link.

Answered by Hosseinmp76

Solution #4

Once fetch supports a ReadableStream as the body, it appears that upload progress will be feasible. This is not yet implemented, but it is being worked on. I believe the code will be similar to this:

warning: this code is not yet functional; we’re waiting for browsers to support it.

To track upload progress instead of fetch(), use XMLHttpRequest – the xhr.upload object generates a progress event.

Answered by jtbandes

Solution #5

It’s not conceivable, in my opinion. The following is taken from the draft:

(Old response): The first example in the chapter on the Fetch API demonstrates how to:

You can see that response, aside from their use of the Promise constructor antipattern. body is a Stream that you can read byte by byte with a Reader, and for each of them you can fire an event or do whatever you want (e.g. track the progress).

However, the Streams standard appears to be incomplete, and I have no idea whether this is already implemented in any fetch implementation.

Answered by Bergi

Post is based on https://stackoverflow.com/questions/35711724/upload-progress-indicators-for-fetch