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

Progress of downloading zip file from s3 presigned url not showing in browsers #780

Open
and-zverev opened this issue Nov 24, 2022 · 5 comments

Comments

@and-zverev
Copy link

and-zverev commented Nov 24, 2022

Hi all!
I'm using a file-saver to save a zip-files from an s3 presigned url - I get a blob from a request and pass it to a file-saver with a custom filename. Now, after the download starts, the file is downloaded in the background and only after the download is completed it immediately appears in the browser download list (and at the bottom panel of Google Chrome f.e.). But I just want to see the progress of downloading the file immediately after the download starts (with the remaining time and the total file size as in the bottom bar, usual for Google Chrome).
According to this guide https://github.com/eligrey/FileSaver.js/wiki/Saving-a-remote-file#using-http-header I added 'Content-Disposition: attachment; filename=some-name.zip' header in s3 presigned url response but it didn't help. I haven't tried other options from this guide as they look like a crutch. But I can be wrong.
What am I doing wrong? What could be the issue? Should I try a different approach? I'll be appreciate for any help.

@and-zverev
Copy link
Author

Hi @eligrey and @jimmywarting, sorry for tagging, but could you take a look at my question above? So that I know should I wait for any answer.

@jimmywarting
Copy link
Collaborator

jimmywarting commented Nov 24, 2022

Need to see some code example both server/client side to be able to help.

I added 'Content-Disposition...
I get a blob from a request and pass it to a file-saver with a custom filename

fyi, you can't use ajax (fetch or xmlhttprequest) to save it...
you should not download any response as a blob.
you need to navigate to the url to start the download. (therefore you must also use a normal GET request, you could use a <form> to change the method and if you also need to send some data or change the request METOD, if you need to add any http header then you could use service workers to attach headers to a request and instead use evt.respondWith)

It says so in the wiki:

When saving remote file then you can't fetch it with AJAX. For a download to begin it has to be navigated to so the browser can do their thing. when using ajax then you take control over it instead.

@and-zverev
Copy link
Author

and-zverev commented Nov 25, 2022

Hi @jimmywarting, thanks for your reply!
I was wrong about the reason for the delay before file downloading. I use fetch to load the file into memory and only then pass it as a blob entirely to the file-saver, which saves it immediately. I followed your advice and navigated on the s3 presigned url programatically, which caused the file to start downloading in the browser, showing progress.
It looks like this:

const link = document.createElement('a');
link.href = url;
link.download = filename;
link.click();

or just:

window.open(url, '_self');

Basically, I'm satisfied with this solution, but I have doubts that this isn't the most efficient/right approach to downloading large files (a few GB) on the client side. Did you mean this approach? Should I look for another solution? FileSystem API implementation, StreamSaver, etc.

@jimmywarting
Copy link
Collaborator

jimmywarting commented Nov 27, 2022

Yea, I assure you that that is the best solution. Old regular Native browser download is better than any js solution. Even for large files. (if it also has content-length and accept byte range, that way you can also pause/resume/continue and retry from where you left of (if it's a good decent browser \w a tiny bit more adv download capability)

@jimmywarting
Copy link
Collaborator

if you have many gigabyte of large files (like up to 4 GiB) then i would also offer a torrent file. there is ways to run torrent clients on a server too. webtorrent is an example of a programmable torrent client that works with both NodeJS and browsers.
torrent can also download from CDNs too. so if there is no peers in the network then it can download from your server as well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants