Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add upload progress callback #183

Open
psixdev opened this issue Oct 5, 2019 · 20 comments
Open

Add upload progress callback #183

psixdev opened this issue Oct 5, 2019 · 20 comments
Labels
enhancement New feature or request help wanted Extra attention is needed

Comments

@psixdev
Copy link

psixdev commented Oct 5, 2019

Hello, I would like to add an image loading indicator. Is this possible when using this library?

@sholladay
Copy link
Collaborator

Did you try the onDownloadProgress callback?

@sholladay sholladay added the question Further information is requested label Oct 6, 2019
@psixdev
Copy link
Author

psixdev commented Oct 6, 2019

Sorry, it seems I did not ask the question correctly. I need upload progress, not download progress. And onDownloadProgress doesn't help me.

@sholladay
Copy link
Collaborator

I see. We don't have that feature at the moment, but it would be nice to add. I think it could be done similarly to download progress.

@sholladay sholladay changed the title Is there any way to find out the progress of loading FormData? Add upload progress callback Oct 7, 2019
@sholladay sholladay added enhancement New feature or request and removed question Further information is requested labels Oct 7, 2019
@sindresorhus sindresorhus added the help wanted Extra attention is needed label Nov 7, 2019
@Qix-
Copy link

Qix- commented Nov 12, 2019

It cannot. ky uses fetch under the hood, which uses streams, which does not support upload progress callbacks.

Seems like a pretty bizarre thing to leave out of the spec, if you ask me. Until they're added, ky cannot support them unless it falls back to XMLHttpRequest.

@sholladay
Copy link
Collaborator

I realize that fetch doesn't have a callback for upload progress, which is a shame. But I think we should be able to detect when options.body is a stream and then send it through a passthrough stream of our own that reads the chunks manually, similarly to how our onDownloadProgress option works.

@Qix-
Copy link

Qix- commented Nov 12, 2019

As long as we can determine the total bytes to be uploaded then absolutely :)

@sholladay
Copy link
Collaborator

I suppose if the body is just a plain stream, we'd only be able to provide how many bytes have been uploaded but not the total bytes, which may not be super useful.

However, if the body is a Blob or a File (or anything that can be normalized to one of those), then we can use blob.size to get the total bytes. And then we can use blob.stream() to get a ReadableStream for it.

@aldipower
Copy link

Really missing this for File uploads. You possible solution sound great @sholladay .

@SupertigerDev
Copy link

can this be added yet? axios seems to have this feature.

@Qix-
Copy link

Qix- commented Dec 9, 2020

@supertiger1234 You are perfectly allowed to submit a PR, yes :)

@SupertigerDev
Copy link

SupertigerDev commented Dec 9, 2020

🤷 I wouldn't even be using a lib for fetching if I knew how.
I am using axios only for when uploading files. Technically i fixed my problem.

@shresthapradip
Copy link

shresthapradip commented Mar 31, 2021

can this be added yet? axios seems to have this feature.

No, I don't think axios supports it for browser. It is only supported in nodejs. Right?

@IRediTOTO
Copy link

Please make this :D

@sholladay
Copy link
Collaborator

For anyone who wants to try implementing this, take a look at #34 and use that as a reference. Once there's a rough draft, I'd be happy to review and help with the code.

@nickchomey
Copy link

nickchomey commented Dec 1, 2022

It seems this should now be possible with Chromium versions > 105. It would be great if it could be incorporated into ky!

https://developer.chrome.com/articles/fetch-streaming-requests/#streaming-request-bodies
fetch() upload streaming - Chrome Platform Status (chromestatus.com)

Here's an example implementation: https://stackoverflow.com/a/52860605/19510854

@Murderlon
Copy link

Murderlon commented Oct 12, 2023

It seems this should now be possible with Chromium versions > 105. It would be great if it could be incorporated into ky!

I've looked into this a bit more and it wouldn't be as easy to implement in ky. The presence of onUploadProgress would have to force the passing of duplex: 'half' to underlying fetch and force the body to be a stream. If you already have the entire file, you have to manually push it through a stream again to count the bytes. When uploading FormData, this would result in hacky conversions which I haven't gotten to work at all. Further more, supporting onUploadProgress would mean dropping support for HTTP/1.1, which frankly is unacceptable. Even giants like AWS S3 still only support uploading over HTTP/1.1.

All in all, I don't see an addition like this making sense until fetch itself exposes more control over this (such as some sort of fetch observer)

@jadedevin13
Copy link

@Murderlon #632 would you mind giving a review?

@mifi
Copy link
Contributor

mifi commented Nov 29, 2024

The problem with #632 is that AFAIK it will crash in browsers other than Chrome which is not really acceptable IMO.

FWIW this person on x implemented a tiny wrapper which uses fetch if the client supports upload progress over fetch, with fallback to XMLHTTPRequest:

I'm not sure if ky could do something like that, e.g. whether ky's API surface can be satisfied using an XMLHttpRequest backend (in addition to fetch).

Alternatively one could make a modified version of the fetch polyfill that exposes its inner XMLHttpRequest object, then ky could hook into its progress event which could be used as a fallback in #632

@sholladay
Copy link
Collaborator

The problem with #632 is that AFAIK it will crash in browsers other than Chrome which is not really acceptable IMO.

True, but only if you provide an onUploadProgress function, which is a new option. It has no impact on existing apps. This is consistent with our approach to other features that don't have wide browser support. Obviously if you need to support Firefox, then you can't use this feature yet. It's still helpful for Chrome users.

The only real alternative here is for us to ignore the option instead of throwing when it's not supported. But silently failing is bad behavior for a library. Instead, you could detect support in your app and selectively provide the onUploadProgress option to achieve the same effect.

To that end, I would be supportive of Ky exporting its feature detection mechanisms. Or moving them to fetch-extras.

FWIW this person on x implemented a tiny wrapper which uses fetch if the client supports upload progress over fetch, with fallback to XMLHTTPRequest

Yep, that's a good approach.

I'm not sure if ky could do something like that, e.g. whether ky's API surface can be satisfied using an XMLHttpRequest backend (in addition to fetch).

It's doable, especially if the goal is only to support this feature and not be a general purpose fallback for fetch. However, there are environments that only support fetch and not XMLHttpRequest, such as Deno, Node, and Cloudflare Workers. So it's only a partial solution.

Whether the complexity is worth it, I'm not sure. I would be happy to look at a PR.

@nichoth
Copy link

nichoth commented Nov 30, 2024

Ky exporting its feature detection mechanisms

Would be a big time saver for me, at least.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests