Saving Files API


#1

I would really like to see a proper API to save files in the browser to my hard drive. This would mean I could open a webpage/webapp and edit documents on a computer/cloud/memory-stick without much effort.

I know there is a lot about security so I think there are only two cases where permission would be granted:

  • An <input type="file" request="save" /> or something to allow writing to existing files
  • A way to select a new file to save to

This would be similar in the way OSX does it’s sandbox for Mac App Store applications.

I know there was some work on this previously, but I would love for it to to get to a stage where it is actually implemented in browsers.


“Save image” feature on mobile platforms
#2

Are you familiar with <a download>? It is implemented as far as I can tell in all browsers. Combined with data or object URLs, you can pretty much save anything that you could possibly generate client-side.


#3

I have seen that but it does not work really well. I want to be able to save files, once given permission, without bugging the user.

Download can just be messy, as each save would put a new file in the downloads or popup a save box. This means autosaving is next to impossible :frowning:


#4

Oh, so you want direct access to the user’s hard disk? That is a much bigger ask. I don’t think even iOS, Android, or Windows 8 give that ability, except perhaps for certain limited folders (e.g. pictures library).


#5

Not directly. Only to the files the user has allowed.

Like the file reading API can only read files dropped on the page or selected through an input, this would have a similar method.


#6

I guess I still don’t understand. <a download> is the current mechanism for explicitly allowing you to save to a file. When you said that wasn’t good enough, you asked about “autosaving” and wanted to avoid “popping up a save box,” and the ability to save files “without bugging the user.”

I don’t see how to reconcile that with “only to the files the user has allowed”—you have to bug the user to ask them which files they allow. You can’t do autosaving, or avoid popping up a save box, since doing so would bypass user permission.

It might be helpful to more concretely outline:

  • What the use case is (in a real world website)
  • What you expect the API to look like
  • At what point the user is, or is not, prompted

#7

I think I know what @kennydude wants. Imagine you build an image editing web app, and the idea is that the user can save her images to disk (but still keep editing them). Today’s solution, using <a download> really sucks: every time she makes an edit and hits save, she gets prompted with a picker -> OK -> You sure you want to replace? -> OK.

I believe that @kennydude wishes to replace that with a situation in which the first time you get prompted in the usual save-as manner, but once that has happened the application can keep a hold on the File (or perhaps only on the Blob, don’t want it changing the name) and can keep saving it. Arguably, this could even be made permanent (if the UA so wished).

Do I get it right @kennydude?


#8

Pretty much

So to be clear on those bullet points:

  • A use a case would be a text editor (really simple). I open a web page, I can open an existing file, edit and save that file (multiple times) without issues. I can also create a new file which I can save to a location I specify on my hard-drive.

  • I expect it to look similar to the file reading api so I could do:

      new FileWriter( evt.target.files[0] ).writeText("Hello World");
    

    and it would work

  • The user would likely see either:

    • An area on an existing file selection box saying “Allow this website to write to this file” (f.e via <input type="text" request="write" /> or something)
    • A new file would be assumed write access. (f.e via <input type="newfile" />)

#9

iOS only allows writing in your sandbox container. There is no user-facing filesystem of any kind, documents are moved from apps through explicit sharing only.

Android’s the same, except not, but it really is. At issue is the SD card, which you can request access to using the WRITE_EXTERNAL_STORAGE permission, which is a free-for-all. Google has been clamping down on this since Android 3.x, where non-primary SD cards (on most phones, the external SD card is non-primary for stupid reasons) require WRITE_MEDIA_STORAGE, which is a Google/OEM-only permission. 4.4 gives auto-generated sandbox container permissions on the SD card and a proper file picker, obsoleting the use of either permission for everything but file managers (which are pretty much screwed on 4.4 devices that follow the WRITE_MEDIA_STORAGE restriction).

Windows is a desktop operating system and thus does not sandbox filesystem access. Modern UI applications on Windows 8, however, are sandboxed, but there’s a sandboxed file picker that grants access to user files. However, most productivity applications on Windows don’t use Modern UI anyway, primarily because secure file pickers hamper their primary use case.

And, on broader points raised in this thread, I would like to point out that it’s fairly difficult to have productivity applications on platforms with no generic file storage. For work apps to, well, work, they need to be able to:

  • Pick files from a user-facing filesystem
  • Write to picked files arbitrarily, for the length of the user session
  • Not be restricted to only picking files the application originated

Notably, you could have a permission-granting file picker ala Android 4.4 and Modern UI Windows.

The tricky part is documents that span multiple files. OSX is a prime offender as they encourage directory hives as a standard way to segregate multiple types of data present in a document, and just structure all the UI to pretend that the documents are actually single files. Also, you have file formats that allow other data to be embedded by linked paths, e.g. a 3D modeler which allows pulling assets from other files. I’m not sure how to handle either usecase as it would require making the user approve opening potentially hundreds of unique file paths every time they want to work with a document, quickly turning into a “mother may I” situation.

Given that the implied use-case is productivity apps I don’t know how to provide these functionalities in ways which are both secure and don’t pose UX issues. In any case, we should not be giving web applications full-disk access.


#10

This is something that has been discussed before, in fact it’s a use case that I’ve previously explained. There is no disagreement that it would be useful, but the devil is in the details.

Some platforms don’t provide general-purpose FS access as @Libertardian correctly points out, but I don’t think that that’s an actual problem. Just because some platforms don’t have {a camera, geolocation, a colour screen, etc.} doesn’t mean we can’t have a given feature. It just means that its behaviour needs to be defined when it can’t physically be supported. (In this case, you probably get nothing or some form of disabled affordance — and that’s okay.)

The problems have more to do with how to scale it both over time and over number of files, without introducing security issues, and while remaining usable.

Let us start small and assume this only works on a file by file case, without handling the directory issue (which as @Libertardian also points out, is likely to confuse people on OSX for some file types). The issue is of extension over time: if I edit my text file using this mechanism and later return to the app, does it automatically have access to that file again? Can I reasonably expect the app’s state to just be restored with the file open and ready to be written?

If the answer is no, there’s a bit of a usability issue (but not a huge one in many cases). If the answer is yes, the situation is more complicated. Maybe I gave access to a web app to write some of my HTML files with, but after a while I realise that they’re doing something I don’t like. I’m not talking about something outright malicious (though that could be the case), just something I’m not happy about. Maybe they add a little tracking code to get an idea of how many people visit pages made with their tool. Maybe they just add a comment pointing to their site. Nothing illegal, but I want them to stop. The problem is: whenever I visit their site (say, because it has great documentation) they regain writing rights to those files and automatically add those annoying comments. This means that users need a clear and simple way in the browser UI to know that a given web app has access to a given set of files (and ways of revoking that). Honestly, I have no idea how to do that cleanly.

The issue of extension over number of files is also annoying. For an image editor in many cases you can probably work fine accessing images one by one (and even then, it depends on the workflow). For a text editor in a great majority of cases you often need access to an entire subdirectory in order to be useful. This could be done: just let people pick a directory, and expose all the files in that. But naturally this increases the danger, and increases the complexity of exposing the user’s actions safely.

Maybe the right approach is to start from a minimal option that can only do one file and only for the lifetime of the given document hosting it. And if that works, build atop it to add more capabilities. But the question is: would something this limited be enough for the functionality to prove useful and take off?


#11

A good way to fill up someone HD. Too easy to exploit IMHO.


#12

Doesn’t the proposed FileSystem API in WebApps address this? It offers a sandbox (with limited quota to avoid the “fill up hard drive” issue) in which the Web App gets total freedom in creating/saving files.


#13

It’s very easy to limit this to either n bytes or an increase of n% if the file was initially already bigger.


#14

That works great if you’re creating the file: you can forever keep it there. But it might be less good for existing files.


#15

@dontcallmedom: yes, the FileSystem API is designed to address this. It’s had fits and starts, but I think it’s safe to assume that we’re mostly in starts still.


#16

I would be very interested to understand what limitations in the FileSystem API don’t quite capture kennydude’s use-cases. I’ve seen developers use it as a sandboxed storage mechanism for apps that, as requested:

  • Open files / allow editing / saving multiple times
  • Create new files with ease

Do you need the ability to write/save multiple data-chunks continuously to disk? Something else?


#17

The FileSystem API is “okay”, but it isn’t what I am looking for, assuming this is the spec you’re talking about.

I would like to be able to access those files outside of the website. What if I wrote a webapp to write novels with, and I moved the website or closed it without notice? I can’t access all of that work now, especially on platforms like Chrome OS and I have lost (potentially) lots of work.

As the developer, I could add Dropbox support. But then User X, Y and Z want Copy.com, Google Drive, FTP and more? However, if I write a native app I don’t have this trouble. Even using something like node-webkit gets around this problem.

Ideally, I want to achieve this in the web browser in a way where by default everyone is happy.

Also thanks to iOS8; I think what I am wanting is achievable on iOS. Android 4.4 implements something similar.


#18

FWIW, this is not the filesystem API we were talking about; http://w3c.github.io/filesystem-api/Overview.html is.