file-system-access
file-system-access copied to clipboard
Add "download" capabilities
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.
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.
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.
dosen't {type: 'saveFile'}
solve the download solution? the only thing i'm missing is the file name (#80)
@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?
@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.
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.
@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.
- 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.
- 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.
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).
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: https://github.com/w3c/strategy/issues/212
The Content Indexing API might also be relevant to surface items made available offline by a web application similar to downloads.
[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
.
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']
}
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?