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 "download" capabilities #29

Open
inexorabletash opened this issue Sep 28, 2018 · 13 comments
Open

Add "download" capabilities #29

inexorabletash opened this issue Sep 28, 2018 · 13 comments
Milestone

Comments

@inexorabletash
Copy link
Member

inexorabletash commented Sep 28, 2018

Right now, web sites can trigger a file download (create an A element, populate href with a blob URL, click() it). This has several important characteristics:

  • The operation is async, and can be throttled by the user agent, e.g. via permission prompts.
  • The file data is immutable by the web app, so it can't be tinkered with after initiating.
  • The user agent can scan potentially dangerous files (executables, archives) for malicious content.
  • The user agent can present the file in a download tray/page/dialog/etc for easy access by the user.

I can imagine ways in which interop with these capabilities would be useful in conjunction with the new features being exposed here:

  • Initiate "download" of a sandboxed file
  • Initiate a "download" of a file to a directory where the web app has write permissions
  • Just better ergonomics over the anchor/href/click dance.
  • Allow creation (under UA control) of "dangerous" files, while still behind user gesture and UA scan.
@mkruisselbrink
Copy link
Contributor

I like the idea. It is a bit unfortunate to have to provide two separate file writing APIs, but it does make a lot of sense to me: allow writing to any type of file using this "write a whole blob to a file" (and maybe "write a whole stream to a file") API (with safe browsing checks etc built in; one open question would be if we would expose the result of safe browsing checks to the website?), while restricting the in some ways more powerful API of writing bytes to arbitrary offsets in existing files to certain less dangerous file types.

@jcubic jcubic mentioned this issue Dec 2, 2018
@camathieu
Copy link

camathieu commented Feb 5, 2019

This would be great. My use case is to trigger a Download, pipe it to a Readable Stream that process the file and save it without having to buffer the whole thing in memory.

Processing could be :

  • client side encryption / decryption
  • client side md5sum/sha-1 checking
  • processing of media streams

Today the only option I'm aware of is https://github.com/jimmywarting/StreamSaver.js. The level of hacking involved proves the need for a simple/clean way to go.

@jimmywarting
Copy link

jimmywarting commented Jan 3, 2020

dosen't {type: 'saveFile'} solve the download solution? the only thing i'm missing is the file name (#80)

@qgustavor
Copy link

qgustavor commented Jan 5, 2020

@jimmywarting I think not.

When set to "saveFile" the dialog will additionally let the
user select files that don't yet exist, and if the user selects a file that does exist already,
its contents will be cleared before the handle is returned to the website.

Because it shows a dialog, depending on the browser, it's different from how currently downloading files works, when no dialog is shown and the file is automatically saved to the download folder. In Firefox, that shows a dialog, after clicking "Save file" it saves automatically to the download folder instead of showing a dialog where the user would choose where to save the file. Depending on the usage it cam reduce friction.

Edit: @DanielHerr What's your point against?

@DanielHerr
Copy link

@inexorabletash Just that currently whether downloads shows a save location dialog is dependent on the user's settings, so "saveFile" might or might not be a similar to downloads.

@dellagustin
Copy link

The use case I am working on is a podcast aggregator. As such, I want to provide the users with the option to download audio files and later play them in the app.
Having an integration with download would be great here.

@pwnall
Copy link
Collaborator

pwnall commented Sep 28, 2020

@dellagustin I acknowledge that my comment falls under "don't do it this way", and therefore may not be as helpful as you'd like. I apologize in advance if that's the case -- I'm posting this hoping it'll help you make progress on your app.

  1. I recommend that you look into the Cache API for your use case. The Cache API has cross-browser support today, and will always let you play back the downloaded resources without any additional prompts.

This API (File System Access) was designed for accessing files that may be shared with other non-Web applications on the user's device. This means we need to make sure that the user doesn't share the files with sites for longer than intended. The consequence is that your app's playback feature may cause the browser to show users permission prompts.

  1. Are you building a web app? If so, heads-up that "downloading" the audio data might be more difficult than expected. You mentioned that you're building an aggregator, so I assume you'd like to fetch audio from different origins. Your app will only be able to fetch https resources served with CORS headers. A workaround for this is to use a CORS proxy, in which case you'll have to pay for the traffic.

Apologies if this already obvious to you. I mentioned this point because the name "download" might suggest that you'd be able to fetch any URL from any site, and this is not the case.

@tomayac
Copy link
Contributor

tomayac commented Sep 28, 2020

The use case I am working on is a podcast aggregator. As such, I want to provide the users with the option to download audio files and later play them in the app.
Having an integration with download would be great here.

Apart from the points mentioned by @pwnall, the Background Fetch API might be an alternative to look into. I have written about how to use it in the context of a podcast app in this article (the article mentions a lot of other best practices at the example of a podcast app, too).

@dellagustin
Copy link

Thank you @pwnall and @tomayac for your comments.

@tomayac the Background Fetch API seems very interesting, I will take a look, the article fits very well to what I am looking for and will be very useful.

@pwnall yes, I am building a web app, and CORS will certainly be a challenge. I already found a workaround for downloading the feeds, as I plan to use the recently created podcastindex.org, but for downloading the files I do not have a solution. I raised this at the w3c strategy repo some time ago, but there was no interaction there yet: w3c/strategy#212

@mkruisselbrink
Copy link
Contributor

mkruisselbrink commented Sep 28, 2020

The Content Indexing API might also be relevant to surface items made available offline by a web application similar to downloads.

@tomayac
Copy link
Contributor

tomayac commented Sep 29, 2020

[https://web.dev/content-indexing-api/](Content Indexing API) classic :-) Here's a stupid mnemonic that helps me remeber the syntax: Bracket [link names](http://my-link-URL-goes-here), avoid braces.

@yisibl
Copy link

yisibl commented Dec 15, 2020

Let me add that downloading with the extension specified by the developer is also part of download compatibility. The current implementation of Chrome cannot fully specify the extension, for example: https://sixth-pushy-dragonfruit.glitch.me/

accept: {
   ['image/*']: ['.jpg']
}

image

@RaiNova
Copy link

RaiNova commented Apr 1, 2022

How about storing data from a web page via drag&drop into a local folder (the web page providing the file name)?
Is this possible already? If not: it would greatly improve the user experience of a website I am working on. Does anybody else see the benefit? Can that functionality be provided with sufficient safety?

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