Note: I'm not looking for any alternatives. I know this can be done with XMLHttpRequest. I also don't care about browser support. I just want learn about the new/upcoming standards.
I have a File object and I can upload it with PUT using fetch like this:
fetch(url, {
method: "PUT",
body: fileObject,
});
How can I get upload progress from this?
From what I understand the body
of the fetch options can be a ReadableStream. So maybe there is a way to wrap the File object to a ReadableStream and get progress status from that?
Eg. something like this
fetch(url, {
method: "PUT",
body: asReadableStream(fileObject, onProgress),
});
Thanks.
// Step 1: start the fetch and obtain a reader let response = await fetch('https://api.github.com/repos/javascript-tutorial/en.javascript.info/commits?per_page=100'); const reader = response. body. getReader(); // Step 2: get total length const contentLength = +response. headers.
The Fetch API allows you to make network requests similar to XMLHttpRequest (XHR). The main difference is that the Fetch API uses Promises, which enables a simpler and cleaner API, avoiding callback hell and having to remember the complex API of XMLHttpRequest.
The Fetch API provides a JavaScript interface for accessing and manipulating parts of the protocol, such as requests and responses. It also provides a global fetch() method that provides an easy, logical way to fetch resources asynchronously across the network.
Chrome started to support streaming uploads https://chromestatus.com/features/5274139738767360
Here is a demo using a pull stream that the request calls when it's ready to accept more data for uploading
let uploaded = 0
let buf = new Uint8Array(1024 * 50)
let start = Date.now()
var rs = new ReadableStream({
pull(ctrl) {
uploaded += buf.byteLength
console.log('uploaded', uploaded)
crypto.getRandomValues(buf)
ctrl.enqueue(buf)
if ((start + 1000) < Date.now()) ctrl.close()
}
})
fetch('https://httpbin.org/post', {
method: 'POST',
body: rs
}).then(r => r.json()).then(console.log)
As Kyle said, ReadableStream uploading is not supported yet. https://github.com/whatwg/fetch/issues/95
Even if it is possible I would not try to monitor the upload progress throught streams, (that is if FetchObserver becomes a thing) Nobody is working on it right now. But Mozilla made a proposal that looks something like this.
/*
enum FetchState {
// Pending states
"requesting", "responding",
// Final states
"aborted", "errored", "complete"
};
*/
fetch(url, {
observe(observer) {
observer.onresponseprogress = e => console.log(e);
observer.onrequestprogress = e => console.log(e);
observer.onstatechange = n => console.log(observer.state)
}
)
I remember that i tested it using some experimental flags a long time ago but can't find the demo anymore, guess they removed it from MDN since it was there own implementation/suggestion.
enqueue bytes to a readable or a identity stream don't mean that you have uploaded the data to the server, it only signals that the request asking for more data to potentially fill up a bucket
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With