-
Notifications
You must be signed in to change notification settings - Fork 2.7k
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
Download API #4148
Comments
+1. I think you would make your case more compelling by showing the problematic example code that you have to use today. (Alternate Bikeshed: /cc @jsbell @mkruisselbrink. Not really related to writable files but kind of in the same ballpark. |
We got native filsystem system also. So do we need this? |
A related case: So needs a callback (or event) to known the download has started. And shows a loading before it starts. |
Such an API would absolutely need to have a way to download streams or download files in pieces. Currently doing this requires a hack using service workers, but these are not available in private mode. Otherwise this wouldn't provide any new functionality.
This is not implemented in Firefox for security reasons. It's also only available in secure contexts. With regards to implementation, I'm not sure whether it should be a method of navigator or of window. |
Oh, btw |
This issue is kind of obsoleted by the existence of the File System Access API, but Mozilla refuses to implement it because it's "harmful". So unless they change their mind, or implement part of it, this issue still stands. |
I don't think File System Access can provide the same protection browsers do for file downloads, nor it can provide good UI for download progress. |
I propose an API like this: {{APIRef("HTML DOM")}} The Syntax
Parameters
Return valueA {{jsxref("Promise")}} that resolves to a ExceptionsThe {{jsxref("Promise")}} may be rejected with one of the following
ExampleThis example downloads a text file containing "Hello, world!" const encoder = new TextEncoder();
const encoded = encoder.encode('Hello, world!');
navigator.download(encoded, {name: 'hello.txt'}); Specifications{{Specifications}} Browser compatibility{{Compat}} |
And the download object: {{APIRef("HTML DOM")}} The Downloads can tell you about how far the file has been downloaded, how big it is (if not a stream), its file name, and when it finishes or aborts. Instance properties
Instance methods
Events
Specifications{{Specifications}} Browser compatibility{{Compat}} |
True. But by not implementing FileSystemDirectoryHandle it wouldn't introduce any unforeseen risks.
Wouldn't FileSystemWritableFileStream enable download progress? The write method is a promise. |
Can I get some feedback on what I proposed? |
I think what needed here is an implementer interest rather than a proposal (although it's also needed too). But anyway: I don't think there's any proven use case to go that far. What's needed here is to be able to download a file and stream without hacking with object URL and service worker and whatnot, and not really about to track and control the download in JS. The user should already be able to do that via the browser UI. |
The downloading of streams is absolutely the most important feature in my opinion. Here's a few use cases.
Being able to abort/finish a download isn't a feature you should omit, especially not when downloading streams. Tracking the progress of a download is also important, at least getting callbacks on errors and completion, to be able to free resources after they have been downloaded. |
Why? Browsers already provide UI for that, why do you need to implement your own?
That's a feature request for streams. I think there was an open issue for that but can't find it... |
Still you have ReadableStream's cancel callback to track the download cancel. You don't need to track completion as you already provided everything in that case, you can immediately free the source in that case. The error, that's a missing thing, but not sure the consumer (a browser here) can cause any error. |
Oh yeah that's true.
This only applies to streams. If downloading a fixed size object it's a different story.
Sure there is. The device can run out of free space for example. The user can abort the download, though that might not be considered an error, but should definitely be an event. I'm sure there's other IO erros that can occur. |
Can you give at example?
I think both should cancel the stream? 🤔 |
To clarify, AFAIK stream readers can't cause an error. And in this case the download is reading the stream, hence a reader. Errors happen from the source side, which devs should be able to catch somehow via try-catch. |
ArrayBuffer, TypedArray, Blob
Possibly, but once again, that's only for streams. I was under the impression that this API would also be for fixed size objects. |
I mean, why do you need a signal for them, you can pass them to the function and forget about them as long as you don't have another reference. |
True, but you might want to do other things when the download has finished. I don't understand why you're insisting on not having a completion event. It only seems reasonable to include it. |
Well, because there should be a very good reason to convince implementers to add something to the web platform 🙂 And since we currently don't have a download API at all, I think it's easier to start small, e.g. a function that receives |
This is the biggest trap in programming. Most of the time you end up with a badly designed system that is hard to extend. How would you add monitoring of progress to the API if the download function call returns a promise that doesn't resolve until download completion? What could also happen is that implementers implement the initial spec, but then delay implementing later additions (cough cough). It's better to do it right from the start. Prove me wrong, but I think implementing a download API is relatively simple in comparison to other APIs (e.g. WebMIDI, Web Audio). No new core functionality has to be implemented really, downloading files is already part of browsers, as are download managers. Downloads already report progress and completion. So I suggest we start by listing all the features that web developers want before defining an initial spec. Then, which the required features in mind, design a mechanism and specification that makes sense to implementers. So far these are my requirements:
I also suspect possible security concerns, which is why I propose the following optional implementation limitations:
|
Sorry, I wasn't clear. I mean maybe resolve it if the browser shows the dialog. (But maybe that's not needed, it's not like there's a long delay.)
Exactly why I want to start small. Implementers can have different opinions and doing everything at once can delay every process. No one wants such situation.
Fair.
Why? Not following the browser behavior is surprising.
What errors? Should it really care whether it's canceled by user or by browser (which is "error" but that should also cancel the stream)
If you really need these, getting a proxy ReadableStream should work for non-stream data too.
While I agree, downloads can already be initiated without interaction AFAIK. Has the situation changed?
I wonder this also applies to existing auto-initiated download mechanism. (A bit out of scope in that case) |
A web developer might want to implement a "save as" button. But IMO it would be acceptable for a browser to prompt the user regardless of whether this parameter is specified.
We talked about this before. Multiple things could cause a download to fail. Lack of storage space, anti virus deleting a downloading file, the user deleting a downloading file, hardware I/O errors.
I know, this limitation might cause problems for web developers and I'd rather not have it, but Mozilla tends to be finicky about standards so I want to stay on the safe side. Ideally we could discuss this with Mozilla devs and get approval though. Perhaps it's best to have it be a setting just like the autoplay setting.
I actually don't know. I might test this. |
What about adding |
In order to avoid having to create URLs from
File
objects, potentially leak the object forever, and navigate some browsing context with such a URL, I was thinking it might be good to have something akinnavigator.download(file)
.The text was updated successfully, but these errors were encountered: