Summary

  • W3C's first public File API Working Draft appeared on 17 November 2009. It described selected files as objects that scripts could read through FileReader, with <input type="file"> as a way for a person to choose them.
  • The 2013 Last Call and 2015 Working Draft developed FileList, Blob, asynchronous reading and blob URLs. A page could preview or parse a chosen file locally; sending its bytes to a server remained a separate application decision.

The clerk at the photo counter asks for one picture. The customer lays it down. The clerk then walks around the counter, opens every drawer in the customer's house and calls this “convenient upload.” Nobody would accept the service. Yet a web application that wanted to work with a local file had to solve a version of that boundary: how could a page receive the useful picture without being handed the whole filesystem?

The answer in the 17 November 2009 First Public Working Draft of the File API began with the file the reader had chosen. Its FileList represented individually selected files. The familiar <input type="file"> was one way to make the selection. A File object carried the selected item's name and media type; Blob represented raw bytes and ranges of those bytes. FileReader could read the file for a script and report its work through events. The page got a useful object. The clerk did not receive a cabinet key.

This changed what an upload button could mean. A classic form could send a file to a server, leaving the user to discover later whether it was the right image. With a file object available to script, a page could inspect or preview the chosen item before deciding what to send. The 2009 draft named three asynchronous reader methods: readAsBinaryString, readAsText and readAsDataURL. A text editor could show the contents of a selected note; a photo page could display a local preview. The interface gave the application a way to handle the bytes without making a round trip merely to see what had been picked.

The draft's own requirements and examples were more interesting than another upload form. One imagined a lyrics viewer opening a chosen playlist file and making it sortable inside the page. Another imagined a calendar application reading a local calendar file and merging entries before any decision about sending it to a server. The examples framed the selected file as material for a web application to work on, not only a parcel to ship away.

Selection was the important hinge. The 2009 security discussion assumed that files read through FileReader had first been selected by the person. It called out an abusive picker that repeatedly demanded a choice, system-sensitive files that should not be exposed, and files changed on disk after selection. Those are not decorative cautions. They show that a file is not a timeless packet already inside the page: it sits in a local environment, can be withheld by the browser, and may change before the read begins. The draft was trying to make a useful local object out of something much less tidy than an HTTP form field.

By the 12 September 2013 Last Call Working Draft, the parts had acquired a clearer division of labor. FileList held the chosen objects. Blob was immutable raw data that could be sliced. File added the local item's name and modification information. FileReader provided asynchronous methods with progress, completion and error events. The draft's example read a selected file as text, updated a progress bar, and handled failures. A large file on a slow or mounted drive could make a page wait; the event model let the page explain the wait instead of freezing like a clerk who had gone to lunch.

The 2013 document also described a blob URL: a browser-held reference to binary data that the page could use where a URL was expected. By the 21 April 2015 Working Draft, the examples showed URL.createObjectURL() feeding a chosen image into page elements and URL.revokeObjectURL() ending that reference when it was no longer needed. This was a practical bridge between a local object and the web's URL-shaped habits. It did not turn a private photograph into a permanent public address. The 2015 draft also described origin-bound blob URLs and failure for cross-origin requests.

One small detail reveals the boundary's temperament. The 2015 File.name exposed the name of a file without its directory path. A page making a preview needed to say which picture it had been given. It did not need a tour of the folders above it. The draft's route from picker to FileList to reader made a selected file legible to software while keeping the scope of that particular handoff narrow.

The browser's restraint should not be confused with a promise about what the page will do next. The File API can provide bytes to a script. An application can then keep those bytes local, transform them, or submit them through another web mechanism. The W3C publication history shows a First Public Working Draft in 2009, a Last Call draft in 2013 and another Working Draft in 2015; it does not turn the API into a single magic moment when every site's behavior became safe. The durable change was a shared representation of what the person had actually chosen.

That representation made web software less clumsy. A photograph could appear before upload; a spreadsheet could be parsed for a preview; a document could be checked before a server saw it. The same parts also exposed the incentives of the page. A good clerk reads the one item handed over and asks what to do with it. A nosy one tries to make the next step invisible. The API made the first act precise enough for the reader, browser and application to know which file crossed the counter.