W3C

File API

Editor's Draft 26 March 2014

This Version:
http://dev.w3.org/2006/webapi/FileAPI/
Latest Published Version:
http://www.w3.org/TR/FileAPI/
Latest Editor’s Draft:
http://dev.w3.org/2006/webapi/FileAPI/
Previous Version(s):
http://www.w3.org/TR/2012/WD-FileAPI-20121025/
Editors:
Arun Ranganathan, Mozilla Corporation <arun@mozilla.com>
Jonas Sicking, Mozilla Corporation <jonas@sicking.cc>
Participate:

Send feedback to public-webapps@w3.org (archives), or file a bug (see existing bugs).


Abstract

This specification provides an API for representing file objects in web applications, as well as programmatically selecting them and accessing their data. This includes:

Additionally, this specification defines objects to be used within threaded web applications for the synchronous reading of files.

The section on Requirements and Use Cases [REQ] covers the motivation behind this specification.

This API is designed to be used in conjunction with other APIs and elements on the web platform, notably: XMLHttpRequest (e.g. with an overloaded send() method for File or Blob arguments), postMessage, DataTransfer (part of the drag and drop API defined in [HTML]) and Web Workers. Additionally, it should be possible to programmatically obtain a list of files from the input element when it is in the File Upload state[HTML]. These kinds of behaviors are defined in the appropriate affiliated specifications.

Status of this Document

This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current W3C publications and the latest revision of this technical report can be found in the W3C technical reports index at http://www.w3.org/TR/.

This document is the 26 March 2014 Editor's Draft of the File API specification. Please send comments about this document to public-webapps@w3.org (archived).

Previous discussion of this specification has taken place on two other mailing lists: public-webapps@w3.org (archive) and public-webapi@w3.org (archive). Ongoing discussion will be on the public-webapps@w3.org mailing list.

This document is produced by the Web Applications WG in the W3C Interaction Domain.

Publication as an Editor's Draft does not imply endorsement by the W3C Membership. This is a draft document and may be updated, replaced or obsoleted by other documents at any time. It is inappropriate to cite this document as other than work in progress.

This document was produced by a group operating under the 5 February 2004 W3C Patent Policy. W3C maintains a public list of any patent disclosures made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s) must disclose the information in accordance with section 6 of the W3C Patent Policy.

This draft consists of changes made to the previous Last Call Working Draft. Please send comments to the public-webapps@w3.org as described above. You can see Last Call Feedback on the W3C Wiki: http://www.w3.org/wiki/Webapps/LCWD-FileAPI-20130912

Table of Contents

1. Introduction

This section is informative.

Web applications should have the ability to manipulate as wide as possible a range of user input, including files that a user may wish to upload to a remote server or manipulate inside a rich web application. This specification defines the basic representations for files, lists of files, errors raised by access to files, and programmatic ways to read files. Additionally, this specification also defines an interface that represents "raw data" which can be asynchronously processed on the main thread of conforming user agents. The interfaces and API defined in this specification can be used with other interfaces and APIs exposed to the web platform.

The File interface represents file data typically obtained from the underlying (OS) file system, and the Blob interface ("Binary Large Object" - a name originally introduced to web APIs in Google Gears) represents immutable raw data. File or Blob reads should happen asynchronously on the main thread, with an optional synchronous API used within threaded web applications. An asynchronous API for reading files prevents blocking and UI "freezing" on a user agent's main thread. This specification defines an asynchronous API based on an event model to read and access a File or Blob's data. A FileReader object provides asynchronous read methods to access that file's data through event handler attributes and the firing of events. The use of events and event handlers allows separate code blocks the ability to monitor the progress of the read (which is particularly useful for remote drives or mounted drives, where file access performance may vary from local drives) and error conditions that may arise during reading of a file. An example will be illustrative.

Example

In the example below, different code blocks handle progress, error, and success conditions.

ECMAScript

function startRead() {  
  // obtain input element through DOM 
  
  var file = document.getElementById('file').files[0];
  if(file){
    getAsText(file);
  }
}

function getAsText(readFile) {
        
  var reader = new FileReader();
  
  // Read file into memory as UTF-16      
  reader.readAsText(readFile, "UTF-16");
  
  // Handle progress, success, and errors
  reader.onprogress = updateProgress;
  reader.onload = loaded;
  reader.onerror = errorHandler;
}

function updateProgress(evt) {
  if (evt.lengthComputable) {
    // evt.loaded and evt.total are ProgressEvent properties
    var loaded = (evt.loaded / evt.total);
    if (loaded < 1) {
      // Increase the prog bar length
      // style.width = (loaded * 200) + "px";
    }
  }
}

function loaded(evt) {  
  // Obtain the read file data    
  var fileString = evt.target.result;
  // Handle UTF-16 file dump
  if(utils.regexp.isChinese(fileString)) {
    //Chinese Characters + Name validation
  }
  else {
    // run other charset test
  }
  // xhr.send(fileString)     
}

function errorHandler(evt) {
  if(evt.target.error.name == "NotReadableError") {
    // The file could not be read
  }
}

2. Conformance

Everything in this specification is normative except for examples and sections marked as being informative.

The keywords “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “RECOMMENDED”, “MAY” and “OPTIONAL” in this document are to be interpreted as described in Key words for use in RFCs to Indicate Requirement Levels [RFC2119].

The following conformance classes are defined by this specification:

conforming user agent

A user agent is considered to be a conforming user agent if it satisfies all of the MUST-, REQUIRED- and SHALL-level criteria in this specification that apply to implementations. This specification uses both the terms "conforming user agent" and "user agent" to refer to this product class.

User agents may implement algorithms in this specifications in any way desired, so long as the end result is indistinguishable from the result that would be obtained from the specification's algorithms.

User agents that use ECMAScript to implement the APIs defined in this specification must implement them in a manner consistent with the ECMAScript Bindings defined in the Web IDL specification [WEBIDL] as this specification uses that specification and terminology.

3. Dependencies

This specification relies on underlying specifications.

DOM

A conforming user agent must support at least the subset of the functionality defined in DOM4 that this specification relies upon; in particular, it must support EventTarget. [DOM4]

Progress Events

A conforming user agent must support the Progress Events specification. Data access on read operations is enabled via Progress Events.[ProgressEvents]

HTML

A conforming user agent must support at least the subset of the functionality defined in HTML that this specification relies upon; in particular, it must support event loops and event handler attributes. [HTML]

Web IDL

A conforming user agent must also be a conforming implementation of the IDL fragments in this specification, as described in the Web IDL specification. [WebIDL]

Typed Arrays

A conforming user agent must support the Typed Arrays specification [TypedArrays].

Parts of this specification rely on the Web Workers specification; for those parts of this specification, the Web Workers specification is a normative dependency. [Workers]

4. Terminology

4.1 Terms

The terms and algorithms document, unloading document cleanup steps, event handler attributes, event handler event type, origin, same origin, effective script origin, incumbent settings object, event loops, task, task source, URL, global script cleanup jobs list, global script cleanup, queue a task, UTF-8, UTF-16. structured clone, collect a sequence of characters and converting a string to ASCII lowercase are as defined by the HTML specification [HTML].

When this specification says to terminate an algorithm the user agent must terminate the algorithm after finishing the step it is on, and return from it. Asynchronous read methods defined in this specification may return before the algorithm in question is terminated, and can be terminated by an abort() call.

The term throw in this specification, as it pertains to exceptions, is used as defined in the DOM4 specification [DOM4].

The term byte in this specification is used as defined in the Encoding Specification [Encoding Specification].

The term context object in this specification is used as defined in the DOM4 specification [DOM4].

The terms parse a URL, scheme, scheme data, query and fragment are as defined by the WHATWG URL Specification [URL].

The terms request and response are as defined in the WHATWG Fetch Specification [Fetch Specification].

The term Unix Epoch is used in this specification to refer to the time 00:00:00 UTC on January 1 1970 (or 1970-01-01T00:00:00Z ISO 8601); this is the same time that is conceptually "0" in ECMA-262 [ECMA-262].

The algorithms and steps in this specification use the following mathematical operations:

  • max(a,b) returns the maximum of a and b, and is always performed on integers as they are defined in WebIDL [WebIDL]; in the case of max(6,4) the result is 6. This operation is also defined in ECMAScript [ECMA-262].

  • min(a,b) returns the minimum of a and b, and is always performed on integers as they are defined in WebIDL [WebIDL]; in the case of min(6,4) the result is 4. This operation is also defined in ECMAScript [ECMA-262].

  • Mathematical comparisons such as < (less than), ≤ (less than or equal to) and > (greater than) are as in ECMAScript [ECMA-262].

5. The Blob Interface and Binary Data

A Blob object refers to a byte sequence, and has a size attribute which is the total number of bytes in the byte sequence, and a type attribute, which is an ASCII-encoded string in lower case representing the media type of the byte sequence.

A Blob must have an internal readability state flag, which is one of OPENED or CLOSED. A Blob that refers to a byte sequence, including one of 0 bytes, is said to be in the OPENED readability state. A Blob is said to be neutered if its close method has been called, in which case it no longer refers to a byte sequence, and must return 0 for its size attribute. A Blob that is neutered is said to be in the CLOSED readability state.

Each Blob must have an internal snapshot state, which must be initially set to the state of the underlying storage, if any such underlying storage exists, and must be preserved through structured clone. Further normative definition of snapshot state can be found for files.

IDL

    [Exposed=Window,Worker][Constructor, 
     Constructor(sequence<(ArrayBuffer or ArrayBufferView or Blob or DOMString)> blobParts, optional BlobPropertyBag options)] 
    interface Blob {
      
      readonly attribute unsigned long long size;
      readonly attribute DOMString type;
      
      //slice Blob into byte-ranged chunks
      
      Blob slice([Clamp] optional long long start,
                 [Clamp] optional long long end,
                 optional DOMString contentType);
      void close(); 
    
    };

    dictionary BlobPropertyBag {
		
      DOMString type = "";
	
    };
    

5.1. Constructors

The Blob() constructor can be invoked with zero or more parameters. When the Blob() constructor is invoked, user agents must run the following Blob constructor steps:

  1. If invoked with zero parameters, return a new Blob object with its readability state set to OPENED, consisting of 0 bytes, with size set to 0, and with type set to the empty string.

  2. Otherwise, the constructor is invoked with a blobParts sequence. Let a be that sequence.

  3. Let bytes be an empty sequence of bytes.

  4. Let length be a's length. For 0 ≤ i < length, repeat the following steps:

    1. Let element be the ith element of a.

    2. If element is a DOMString, run the following substeps:

      1. Let s be the result of converting element to a sequence of Unicode characters [Unicode] using the algorithm for doing so in WebIDL [WebIDL].

      2. Encode s as UTF-8 and append the resulting bytes to bytes.

      Note

      The algorithm from WebIDL [WebIDL] replaces unmatched surrogates in an invalid UTF-16 string with U+FFFD replacement characters. Scenarios exist when the Blob constructor may result in some data loss due to lost or scrambled character sequences.

    3. If element is an ArrayBufferView [TypedArrays], convert it to a sequence of byteLength bytes from the underlying ArrayBuffer, starting at the byteOffset of the ArrayBufferView [TypedArrays], and append those bytes to bytes.

    4. If element is an ArrayBuffer [TypedArrays], convert it to a sequence of byteLength bytes, and append those bytes to bytes.

    5. If element is a Blob, append the bytes it represents to bytes. The type of the Blob array element is ignored.

  5. If the type member of the optional options argument is provided and is not the empty string, run the following sub-steps:

    1. Let t be the type dictionary member. If t contains any characters outside the range U+0020 to U+007E, then set t to the empty string and return from these substeps.
    2. Convert every character in t to lowercase using the "converting a string to ASCII lowercase" algorithm [WebIDL].
  6. Return a Blob object with its readability state set to OPENED, referring to bytes as its associated byte sequence, with its size set to the length of bytes, and its type set to the value of t from the substeps above.

    Note

    The type t of a Blob is considered a parsable MIME type if the ASCII-encoded string representing the Blob object's type, when converted to a byte sequence, does not return undefined for the parse MIME type algorithm [MIMESNIFF].

5.1.1. Constructor Parameters

The Blob() constructor can be invoked with the parameters below:

A blobParts sequence
which takes any number of the following types of elements, and in any order:
An optional BlobPropertyBag
which takes one member:
  • type, the ASCII-encoded string in lower case representing the media type of the Blob. Normative conditions for this member are provided in the Blob constructor steps.
Example

Examples of constructor usage follow.

ECMAScript

// Create a new Blob object

var a = new Blob();

// Create a 1024-byte ArrayBuffer
// buffer could also come from reading a File

var buffer = new ArrayBuffer(1024);

// Create ArrayBufferView objects based on buffer

var shorts = new Uint16Array(buffer, 512, 128);
var bytes = new Uint8Array(buffer, shorts.byteOffset + shorts.byteLength);

var b = new Blob(["foobarbazetcetc" + "birdiebirdieboo"], {type: "text/plain;charset=UTF-8"});

var c = new Blob([b, shorts]);

var a = new Blob([b, c, bytes]);

var d = new Blob([buffer, b, c, bytes]);

5.2. Attributes

size

Returns the size of the byte sequence in number of bytes. On getting, conforming user agents must return the total number of bytes that can be read by a FileReader or FileReaderSync object, or 0 if the Blob has no bytes to be read. If the Blob has a readability state of CLOSED then size must return 0.

type

The ASCII-encoded string in lower case representing the media type of the Blob. On getting, user agents must return the type of a Blob as an ASCII-encoded string in lower case, such that when it is converted to a byte sequence, it is a parsable MIME type [MIMESNIFF], or the empty string -- 0 bytes -- if the type cannot be determined. The type attribute can be set by the web application itself through constructor invocation and through the slice call; in these cases, further normative conditions for this attribute are in the Blob constructor steps, the File Constructor steps, and the slice method algorithm respectively. User agents can also determine the type of a Blob, especially if the byte sequence is from an on-disk file; in this case, further normative conditions are in the file type guidelines..

Note

Use of the type attribute informs the encoding determination and parsing the Content-Type header when dereferencing blob: URLs.

5.3. Methods and Parameters

5.3.1. The slice method

The slice method returns a new Blob object with bytes ranging from the optional start parameter upto but not including the optional end parameter, and with a type attribute that is the value of the optional contentType parameter. It must act as follows :

  1. Let O be the Blob context object on which the slice method is being called. If O has a readability state of CLOSED, throw an InvalidStateError exception [DOM4] and terminate this algorithm.

  2. Otherwise, the optional start parameter is a value for the start point of a slice call, and must be treated as a byte-order position, with the zeroth position representing the first byte. User agents must process slice with start normalized according to the following:

    1. If the optional start parameter is not used as a parameter when making this call, let relativeStart be 0.

    2. If start is negative, let relativeStart be max((size + start), 0).

    3. Else, let relativeStart be min(start, size).

  3. The optional end parameter is a value for the end point of a slice call. User agents must process slice with end normalized according to the following:

    1. If the optional end parameter is not used as a parameter when making this call, let relativeEnd be size.

    2. If end is negative, let relativeEnd be max((size + end), 0)

    3. Else, let relativeEnd be min(end, size)

  4. The optional contentType parameter is used to set the ASCII-encoded string in lower case representing the media type of the Blob. User agents must process the slice with contentType normalized according to the following:

    1. If the contentType parameter is not provided, let relativeContentType be set to the empty string .

    2. Else let relativeContentType be set to contentType and run the substeps below:

      1. If relativeContentType contains any characters outside the range of U+0020 to U+007E, then set relativeContentType to the empty string and return from these substeps.
      2. Convert every character in relativeContentType to lower case using the "Converting a string to ASCII lowercase" algorithm.
  5. Let span be max((relativeEnd - relativeStart), 0).

  6. Return a new Blob object S with the following characteristics:

    1. S has a readability state of OPENED.

    2. S refers to span consecutive bytes from O, beginning with the byte at byte-order position relativeStart.

    3. S.size = span.

    4. S.type = relativeContentType.

      Note

      The type t of a Blob is considered a parsable MIME type if the ASCII-encoded string representing the Blob object's type, when converted to a byte sequence, does not return undefined for the parse MIME type algorithm [MIMESNIFF].

Example

The examples below illustrate the different types of slice calls possible. Since the File interface inherits from the Blob interface, examples are based on the use of the File interface.

ECMAScript

    // obtain input element through DOM
    
    var file = document.getElementById('file').files[0];
    if(file)
    {
      // create an identical copy of file
      // the two calls below are equivalent
      
      var fileClone = file.slice(); 
      var fileClone2 = file.slice(0, file.size);
      
      // slice file into 1/2 chunk starting at middle of file
      // Note the use of negative number
      
      var fileChunkFromEnd = file.slice(-(Math.round(file.size/2)));
      
      // slice file into 1/2 chunk starting at beginning of file
      
      var fileChunkFromStart = file.slice(0, Math.round(file.size/2));
      
      // slice file from beginning till 150 bytes before end
      
      var fileNoMetadata = file.slice(0, -150, "application/experimental");      
    }
    

5.3.2. The close method

The close method is said to neuter a Blob, and must act as follows on the Blob on which the method has been called:

  1. If the readability state of the context object is CLOSED, throw an InvalidStateError and terminate this algorithm.

  2. Otherwise, set the context object to no longer refer to a byte sequence.

  3. Set the readability state of the context object to CLOSED.

  4. Set the size of the context object to 0.

  5. If the context object has an entry in the Blob URL Store, remove the entry for this Blob.

Note

Neutering a Blob decouples it from any binary data it may have referred to. User agents may engage in any affiliated garbage collection.

6. The File Interface

A File object is a Blob object with a name attribute, which is a string; it can be created within the web application via a constructor, or is a reference to a byte sequence from a file from the underlying (OS) file system.

If a File object is a reference to a byte sequence originating from a file on disk, then its snapshot state should be set to the state of the file on disk at the time the File object is created.

Note

This is a non-trivial requirement to implement for user agents, and is thus not a must but a should [RFC2119]. User agents should endeavor to have a File object's snapshot state set to the state of the underlying storage on disk at the time the reference is taken. If the file is modified on disk following the time a reference has been taken, the File's snapshot state will differ from the state of the underlying storage. User agents may use modification time stamps and other mechanisms to maintain snapshot state, but this is left as an implementation detail.

When a File object refers to a file on disk, user agents must return the type of that file, and must follow the file type guidelines below:

IDL

[Exposed=Window,Worker][Constructor(sequence<(Blob or DOMString or ArrayBufferView or ArrayBuffer)> fileBits, 
[EnsureUTF16] DOMString fileName, optional FilePropertyBag options)]
interface File : Blob {

  readonly attribute DOMString name;
  readonly attribute long long lastModified;

};

dictionary FilePropertyBag {
    
      DOMString type = "";
      long long lastModified;
  
};
	  

6.1 Constructor

The File constructor is invoked with two or three parameters, depending on whether the optional dictionary parameter is used. When the File() constructor is invoked, user agents must run the following File constructor steps:

  1. Let a be the fileBits sequence argument. Let bytes be an empty sequence of bytes. Let length be a's length. For 0 ≤ i < length, repeat the following steps:
    1. Let element be the i'th element of a.
    2. If element is a DOMString, run the following substeps:
      1. Let s be the result of converting element to a sequence of Unicode characters [Unicode] using the algorithm for doing so in WebIDL [WebIDL].

      2. Encode s as UTF-8 and append the resulting bytes to bytes.

      Note

      The algorithm from WebIDL [WebIDL] replaces unmatched surrogates in an invalid UTF-16 string with U+FFFD replacement characters. Scenarios exist when the Blob constructor may result in some data loss due to lost or scrambled character sequences.

    3. If element is an ArrayBufferView [TypedArrays], convert it to a sequence of byteLength bytes from the underlying ArrayBuffer, starting at the byteOffset of the ArrayBufferView [TypedArrays], and append those bytes to bytes.
    4. If element is an ArrayBuffer [TypedArrays], convert it to a sequence of byteLength bytes, and append those bytes to bytes.

    5. If element is a Blob, append the bytes it represents to bytes. The type of the Blob argument must be ignored.

  2. Let n be a new string of the same size as the fileName argument to the constructor. Copy every character from fileName to n, replacing any "/" character (U+002F SOLIDUS) with a ":" (U+003A COLON).
    Note

    Underlying OS filesystems use differing conventions for file name; with constructed files, mandating UTF-16 lessens ambiquity when file names are converted to byte sequences.

  3. If the optional FilePropertyBag dictionary argument is used, then run the following substeps:
    1. If the type member is provided and is not the empty string, let t be set to the type dictionary member. If t contains any characters outside the range U+0020 to U+007E, then set t to the empty string and return from these substeps.
    2. Convert every character in t to lowercase using the "converting a string to ASCII lowercase algorithm" [WebIDL].
    3. If the lastModified member is provided, let d be set to the lastModified dictionary member. If it is not provided, set d to the current date and time represented as the number of milliseconds since the Unix Epoch (which is the equivalent of Date.now() [ECMA-262]).
      Note

      Since ECMA-262 Date objects convert to long long values representing the number of milliseconds since the Unix Epoch, the lastModified member could be a Date object [ECMA-262].

  4. Return a new File object F such that:
    1. F has a readability state of OPENED.
    2. F refers to the bytes byte sequence.
    3. F.size is set to the number of total bytes in bytes.
    4. F.name is set to n.
    5. F.type is set to t.
      Note

      The type t of a File is considered a parsable MIME type if the ASCII-encoded string representing the File object's type, when converted to a byte sequence, does not return undefined for the parse MIME type algorithm [MIMESNIFF].

    6. F.lastModified is set to d.

6.1.1 Constructor Parameters

The File() constructor can be invoked with the parameters below:

A fileBits sequence
which takes any number of the following elements, and in any order:
A name parameter

A DOMString [WebIDL] parameter representing the name of the file; normative conditions for this constructor parameter can be found in the File constructor steps.

An optional FilePropertyBag dictionary

which takes the following members:

  • An optional type member; normative conditions for this member are provided in the File constructor steps .

  • An optional lastModified member, which must be a long long; normative conditions for this member are provided in the File constructor steps.

6.2. Attributes

name

The name of the file; on getting, this must return the name of the file as a string. There are numerous file name variations and conventions used by different underlying OS file systems; this is merely the name of the file, without path information. On getting, if user agents cannot make this information available, they must return the empty string. If a File object is created using a constructor, further normative conditions for this attribute are found in the file constructor steps.

lastModified

The last modified date of the file. On getting, if user agents can make this information available, this must return a long long set to the time the file was last modified as the number of milliseconds since the Unix Epoch. If the last modification date and time are not known, the attribute must return the current date and time as a long long representing the number of milliseconds since the Unix Epoch; this is equivalent to Date.now() [ECMA-262]. If a File object is created using a constructor, further normative conditions for this attribute are found in the file constructor steps.

The File interface is available on objects that expose an attribute of type FileList; these objects are defined in HTML [HTML]. The File interface, which inherits from Blob, is immutable, and thus represents file data that can be read into memory at the time a read operation is initiated. User agents must process reads on files that no longer exist at the time of read as errors, throwing a NotFoundError exception if using a FileReaderSync on a Web Worker [Workers] or firing an error event with the error attribute returning a NotFoundError DOMError.

Example

In the examples below, metadata from a file object is displayed meaningfully, and a file object is created with a name and a last modified date.

ECMAScript

var file = document.getElementById("filePicker").files[0];
var date = new Date(file.lastModified);
println("You selected the file " + file.name + " which was modified on " + date.toDateString() + " .");

...

// Generate a file with a specific last modified date

var d = new Date(2013, 12, 5, 16, 23, 45, 600);
var generatedFile = new File(["Rough Draft ...."], "Draft1.txt", {type: "text/plain"; lastModified: d})

...

7. The FileList Interface

This interface is a list of File objects.

IDL

    [Exposed=Window,Worker] interface FileList {
      getter File? item(unsigned long index);
      readonly attribute unsigned long length;
    };
    
Example

Sample usage typically involves DOM access to the <input type="file"> element within a form, and then accessing selected files.

ECMAScript

    // uploadData is a form element
    // fileChooser is input element of type 'file'
    var file = document.forms['uploadData']['fileChooser'].files[0];
    
    // alternative syntax can be
    // var file = document.forms['uploadData']['fileChooser'].files.item(0);
    
    if(file)
    {
      // Perform file ops
    }  
    

7.1. Attributes

length

must return the number of files in the FileList object. If there are no files, this attribute must return 0.

7.2. Methods and Parameters

item(index)

must return the indexth File object in the FileList. If there is no indexth File object in the FileList, then this method must return null.

index must be treated by user agents as value for the position of a File object in the FileList, with 0 representing the first file. Supported property indices [WebIDL] are the numbers in the range zero to one less than the number of File objects represented by the FileList object. If there are no such File objects, then there are no supported property indices [WebIDL].

Note
The HTMLInputElement interface [HTML] has a readonly attribute of type FileList, which is what is being accessed in the above example. Other interfaces with a readonly attribute of type FileList include the DataTransfer interface [HTML].

8. Reading Data

8.1 The Read Operation

The algorithm below defines a read operation, which takes a Blob and a synchronous flag as input, and reads bytes into system memory as the result of the read operation, or else returns failure. The result of the read operation consists of bytes in system memory. Methods in this specification invoke the read operation with the synchronous flag either set or unset.

The synchronous flag determines if a read operation is synchronous or asynchronous, and is unset by default. Methods may set it. If it is set, the read operation takes place synchronously. Otherwise, it takes place asynchronously, and queues tasks annotated process read, process read data, and process read EOF for the result on the file reading task source.

To perform a read operation on an input consisting of a Blob and the synchronous flag, run the following steps:

  1. Set result to null initially.

  2. If the readability state of the Blob is CLOSED, return failure and terminate this algorithm.

  3. If the synchronous flag is set, run the following substeps:

    1. Start reading bytes from the input Blob into result. If an error occurs reading the Blob, return failure and terminate this algorithm.
      Note

      Along with returning failure, this algorithm must return the type of error that occurred for throwing an exception by synchronous methods that invoke this algorithm with the synchronous flag set.

    2. When all the bytes from the input Blob have been read into system memory, return them as result and terminate this algorithm.
  4. Otherwise, process the rest of this algorithm asynchronously, and run the following substeps.

    1. If an error occurs reading the input Blob, return failure and terminate this algorithm.
      Note

      Along with returning failure, this algorithm must return the type of error that occurred to asynchronous methods that invoke this algorithm with the synchronous flag unset, to enable asynchronous error reporting.

    2. Otherwise, queue a task to process read, which starts reading bytes from the input Blob into result .

    3. Then, either once result has at least one byte read into it or there are no bytes to read, queue a task to process read data for result. Keep queuing tasks to process read data every 50ms or for each byte of the input Blob read into result, whichever is least frequent.

    4. Then, once result consists of all the bytes of the input Blob in system memory, queue a task to process read EOF.

    Use the file reading task source for these tasks.

8.2. The File Reading Task Source

This specification defines a new generic task source called the file reading task source, which is used for all tasks that are queued in this specification to read byte sequences associated with Blob and File objects, and also for all events that are fired at the FileReader. It is to be used for features that trigger in response to asynchronously reading binary data.

8.3 The FileReader API

IDL


	[Exposed=Window,Worker][Constructor]
	interface FileReader: EventTarget {

	  // async read methods
	  void readAsArrayBuffer(Blob blob);
	  void readAsText(Blob blob, optional DOMString label);
	  void readAsDataURL(Blob blob);

	  void abort();

	  // states
	  const unsigned short EMPTY = 0;
	  const unsigned short LOADING = 1;
	  const unsigned short DONE = 2;


	  readonly attribute unsigned short readyState;

	  // File or Blob data
	  readonly attribute (DOMString or ArrayBuffer)? result;

	  readonly attribute DOMError? error;

	  // event handler attributes
	  attribute EventHandler onloadstart;
	  attribute EventHandler onprogress;
	  attribute EventHandler onload;
	  attribute EventHandler onabort;
	  attribute EventHandler onerror;
	  attribute EventHandler onloadend;

	};
	  

8.3.1. Constructors

When the FileReader() constructor is invoked, the user agent must return a new FileReader object.

In environments where the global object is represented by a Window or a WorkerGlobalScope object, the FileReader constructor must be available.

8.3.2. Event Handler Attributes

The following are the event handler attributes (and their corresponding event handler event types) that user agents must support on FileReader as DOM attributes:

event handler attribute event handler event type
onloadstart loadstart
onprogress progress
onabort abort
onerror error
onload load
onloadend loadend

8.3.3. FileReader States

The FileReader object can be in one of 3 states. The readyState attribute, on getting, must return the current state, which must be one of the following values:

EMPTY (numeric value 0)

The FileReader object has been constructed, and there are no pending reads. None of the read methods have been called. This is the default state of a newly minted FileReader object, until one of the read methods have been called on it.

LOADING (numeric value 1)

A File or Blob is being read. One of the read methods is being processed, and no error has occurred during the read.

DONE (numeric value 2)

The entire File or Blob has been read into memory, OR a file error occurred during read, OR the read was aborted using abort(). The FileReader is no longer reading a File or Blob. If readyState is set to DONE it means at least one of the read methods have been called on this FileReader.

8.3.4. Reading a File or Blob

Multiple Reads

The FileReader interface makes available three asynchronous read methods - readAsArrayBuffer, readAsText, and readAsDataURL, which read files into memory. If multiple concurrent read methods are called on the same FileReader object, user agents must throw an InvalidStateError [DOM4] on any of the read methods that occur when readyState = LOADING.

8.3.4.1. The result attribute

On getting, the result attribute returns a Blob's data as a DOMString, or as an ArrayBuffer [TypedArrays], or null, depending on the read method that has been called on the FileReader, and any errors that may have occurred. The list below is normative for the result attribute and is the conformance criteria for this attribute:

  • On getting, if the readyState is EMPTY (no read method has been called) then the result attribute must return null.

  • On getting, if an error in reading the File or Blob has occurred (using any read method), then the result attribute must return null.

  • On getting, if the readAsDataURL read method is used, the result attribute must return a DOMString that is a Data URL [DataURL] encoding of the File or Blob's data.

  • On getting, if the readAsText read method is called and no error in reading the File or Blob has occurred, then the result attribute must return a string representing the File or Blob's data as a text string, and should decode the string into memory in the format specified by the encoding determination as a DOMString.

  • On getting, if the readAsArrayBuffer read method is called and no error in reading the File or Blob has occurred, then the result attribute must return an ArrayBuffer [TypedArrays] object.

8.3.4.2. The readAsDataURL(blob) method

When the readAsDataURL(blob) method is called, the user agent must run the steps below.

  1. If readyState = LOADING throw an InvalidStateError exception [DOM4] and terminate this algorithm.

    Note: The readAsDataURL() method returns due to the algorithm being terminated.

  2. If the blob has been neutered through the close method, throw an InvalidStateError exception [DOM4] and terminate this algorithm.

    Note: The readAsDataURL() method returns due to the algorithm being terminated.

  3. Otherwise initiate a read operation using the blob argument and with the synchronous flag unset. If the read operation returns failure, set readyState to DONE and set result to null if it is not already set to null. Proceed to the error steps.

    Note

    The read operation also returns the cause of failure for use with the error steps.

  4. If no error has occurred, set readyState to LOADING and handle tasks queued on the file reading task source per below.

  5. To process read fire a progress event called loadstart at the FileReader.

  6. To process read data fire a progress event called progress at the FileReader.

  7. To process read EOF run these substeps:

    1. Set readyState to DONE.

    2. Set the result attribute to the result of the read operation as a DataURL [DataURL]; on getting, the result attribute returns the (complete) data of blob as a Data URL [DataURL].

      • Use the blob's type attribute as part of the Data URL if it is available in keeping with the Data URL specification [DataURL].

      • If the type attribute is not available on the blob return a Data URL without a media-type. [DataURL].

        Data URLs that do not have media-types [RFC2046] must be treated as plain text by conforming user agents. [DataURL].

    3. Fire a progress event called load at the FileReader.
    4. Unless readyState is LOADING fire a progress event called loadend at the FileReader. If readyState is LOADING do NOT fire loadend at the FileReader.
  8. Terminate this algorithm.

8.3.4.3. The readAsText(blob, label) method

The readAsText() method can be called with an optional parameter, label, which is a DOMString argument that represents the label of an encoding [Encoding Specification]; if provided, it must be used as part of the encoding determination used when processing this method call.

When the readAsText(blob, label) method is called (the label argument is optional), the user agent must run the steps below.

  1. If readyState = LOADING throw an InvalidStateError [DOM4] and terminate these steps.

    Note: The readAsText() method returns due to the algorithm being terminated.

  2. If the blob has been neutered through the close method, throw an InvalidStateError exception [DOM4] and terminate this algorithm.

    Note: The readAsText() method returns due to the algorithm being terminated.

  3. Otherwise, initiate a read operation using the blob argument and with the synchronous flag unset. If the read operation returns failure, set readyState to DONE and set result to null if it is not already set to null. Proceed to the error steps.

    Note

    The read operation also returns the cause of failure for use with the error steps.

  4. If no error has occurred, set readyState to LOADING and handle tasks queued on the file reading task source per below.

  5. To process read fire a progress event called loadstart at the FileReader.

  6. To process read data fire a progress event called progress at the FileReader.

  7. To process read EOF run these substeps:

    1. Set readyState to DONE

    2. Set the result attribute to the result of the read operation, represented as a string in a format determined by the encoding determination.

    3. Fire a progress event called load at the FileReader.
    4. Unless readyState is LOADING fire a progress event called loadend at the FileReader. If readyState is LOADING do NOT fire loadend at the FileReader.
  8. Terminate this algorithm.

8.3.4.4. The readAsArrayBuffer(blob) method

When the readAsArrayBuffer(blob) method is called, the user agent must run the steps below.

  1. If readyState = LOADING throw an InvalidStateError exception [DOM4] and terminate these steps.

    Note: The readAsArrayBuffer() method returns due to the algorithm being terminated.

  2. If the blob has been neutered through the close method, throw an InvalidStateError exception [DOM4] and terminate this algorithm.

    Note: The readAsArrayBuffer() method returns due to the algorithm being terminated.

  3. Otherwise, initiate a read operation using the blob argument and with the synchronous flag unset. If the read operation returns failure, set readyState to DONE and set result to null if it is not already set to null. Proceed to the error steps.

    Note

    The read operation also returns the cause of failure for use with the error steps.

  4. If no error has occurred, set readyState to LOADING and handle tasks queued on the file reading task source per below.

  5. To process read fire a progress event called loadstart at the FileReader.

  6. To process read data fire a progress event called progress at the FileReader.

  7. To process read EOF run these substeps:

    1. Set readyState to DONE

    2. Set the result attribute to the result of the read operation as an ArrayBuffer [TypedArrays] object.

    3. Fire a progress event called load at the FileReader.

    4. Unless readyState is LOADING fire a progress event called loadend at the FileReader. If readyState is LOADING do NOT fire loadend at the FileReader.

  8. Terminate this algorithm.

8.3.4.5. Error Steps
  1. Set the error attribute; on getting, the error attribute must be a a DOMError object that indicates the kind of file error that has occurred. Fire a progress event called error.

  2. Unless readyState is LOADING, fire a progress event called loadend. If readyState is LOADING do NOT fire loadend.

  3. Terminate the algorithm for any read method.

    Note: The read method returns due to the algorithm being terminated.

8.3.4.6. The abort() method

When the abort() method is called, the user agent must run the steps below:

  1. If readyState = EMPTY or if readyState = DONE set result to null and terminate this overall set of steps without doing anything else.

  2. If readyState = LOADING set readyState to DONE and result to null.

  3. If there are any tasks from the context object on the file reading task source in an affiliated task queue, then remove those tasks from that task queue.

  4. Terminate the algorithm for the read method being processed.

  5. Fire a progress event called abort

  6. Fire a progress event called loadend.

8.3.4.7. Blob Parameters

The three asynchronous read methods, the three synchronous read methods, and createObjectURL take a Blob parameter. This section defines this parameter.

blob

This is a Blob argument and must be a reference to a single File in a FileList or a Blob object not obtained from the file system.

8.4. Determining Encoding

When reading blob objects using the readAsText() read method, the following encoding determination steps must be followed:

  1. Let encoding be null

  2. If the label argument is present when calling the method, set encoding to the result of "getting an encoding" using the Encoding Specification [Encoding Specification] for label.

  3. If the "getting an encoding" steps above return failure, then set encoding to null.

  4. If encoding is null, and the blob argument's type attribute is present, and it uses a Charset Parameter [RFC2046], set encoding to the result of "getting an encoding" using the Encoding Specification [Encoding Specification] for the portion of the Charset Parameter that is a label of an encoding.

    Example

    If blob has a type attribute of text/plain;charset=UTF-8 then "getting an encoding" is run using UTF-8 as the label. Note that user agents must parse and extract the portion of the Charset Parameter that constitutes a label of an encoding.

  5. If the "getting an encoding" steps above return failure, then set encoding to null.

  6. If encoding is null, then set encoding to utf-8.

  7. "Decode" [Encoding Specification] this blob using fallback encoding encoding, and return the result. On getting, the result attribute of the FileReader object returns a string in encoding format. The synchronous readAsText method of the FileReaderSync object returns a string in encoding format.

8.5.10. Events

The FileReader object must be the event target for all events in this specification.

When this specification says to fire a progress event called e (for some ProgressEvent e at a given FileReader reader as the context object), the following are normative:

  • The progress event e does not bubble. e.bubbles must be false [DOM4]

  • The progress event e is NOT cancelable. e.cancelable must be false [DOM4]

  • The term "fire an event" is defined in DOM Core [DOM4]. Progress Events are defined in Progress Events [ProgressEvents].

8.5.10.1. Event Summary

The following are the events that are fired at FileReader objects; firing events is defined in DOM Core [DOM4].

Event name Interface Fired when…
loadstart ProgressEvent When the read starts.
progress ProgressEvent While reading (and decoding) blob
abort ProgressEvent When the read has been aborted. For instance, by invoking the abort() method.
error ProgressEvent When the read has failed (see errors).
load ProgressEvent When the read has successfully completed.
loadend ProgressEvent When the request has completed (either in success or failure).

8.5.10.2. Summary of Event Invariants

This section is informative. The following are invariants applicable to event firing for a given asynchronous read method in this specification:

  1. Once a loadstart has been fired, a corresponding loadend fires at completion of the read, EXCEPT if

    • the read method has been cancelled using abort() and a new read method has been invoked;

    • the event handler function for a load event initiates a new read;

    • the event handler function for a error event initiates a new read.

    Note
    The events loadstart and loadend are not coupled in a one-to-one manner.
    Example

    This example showcases "read-chaining" namely initiating another read from within an event handler while the "first" read continues processing.

    ECMAScript
    
        // In code of the sort...
        reader.readAsText(file);
        reader.onload = function(){reader.readAsText(alternateFile);}
        
        .....
    
        //... the loadend event must not fire for the first read
    
        reader.readAsText(file);
        reader.abort();
        reader.onabort = function(){reader.readAsText(updatedFile);}
    
        //... the loadend event must not fire for the first read
         
        
  2. One progress event will fire when blob has been completely read into memory.

  3. No progress event fires before loadstart.

  4. No progress event fires after any one of abort, load, and error have fired. At most one of abort, load, and error fire for a given read.

  5. No abort, load, or error event fires after loadend.

8.6 Reading on Threads

Web Workers allow for the use of synchronous File or Blob read APIs, since such reads on threads do not block the main thread. This section defines a synchronous API, which can be used within Workers [Web Workers]. Workers can avail of both the asynchronous API (the FileReader object) and the synchronous API (the FileReaderSync object).

8.6.1. The FileReaderSync API

This interface provides methods to synchronously read File or Blob objects into memory.

IDL


	[Exposed=Worker][Constructor]
	interface FileReaderSync {

	  // Synchronously return strings

	  ArrayBuffer readAsArrayBuffer(Blob blob); 
	  DOMString readAsText(Blob blob, optional DOMString label);
	  DOMString readAsDataURL(Blob blob);
	};
	
8.6.1.1. Constructors

When the FileReaderSync() constructor is invoked, the user agent must return a new FileReaderSync object.

In environments where the global object is represented by a WorkerGlobalScope object, the FileReaderSync constructor must be available.

8.6.1.2. The readAsText method

When the readAsText(blob, label) method is called (the label argument is optional), the following steps must be followed:

  1. If readyState = LOADING throw an InvalidStateError exception [DOM4] and terminate these steps.

    Note: The method returns due to the algorithm being terminated.

  2. If the blob has been neutered through the close method, throw an InvalidStateError exception [DOM4] and terminate this algorithm.

    Note: The method returns due to the algorithm being terminated.

  3. Otherwise, initiate a read operation using the blob argument, and with the synchronous flag set. If the read operation returns failure, throw the appropriate exception. Terminate this algorithm.

  4. If no error has occurred, return the result of the read operation represented as a string in a format determined through the encoding determination algorithm.

8.6.1.3. The readAsDataURL method

When the readAsDataURL(blob) method is called, the following steps must be followed:

  1. If readyState = LOADING throw an InvalidStateError exception [DOM4] and terminate these steps.

    Note: The method returns due to the algorithm being terminated.

  2. If the blob has been neutered through the close method, throw an InvalidStateError exception [DOM4] and terminate this algorithm.

    Note: The method returns due to the algorithm being terminated.

  3. Otherwise, initiate a read operation using the blob argument, and with the synchronous flag set. If the read operation returns failure, throw the appropriate exception. Terminate this algorithm.

  4. If no error has occurred, return the result of the read operation as a Data URL [DataURL] subject to the considerations below.

    • Use the blob's type attribute as part of the Data URL if it is available in keeping with the Data URL specification [DataURL] .
    • If the type attribute is not available on the blob return a Data URL without a media-type. [DataURL].

      Data URLs that do not have media-types [RFC2046] must be treated as plain text by conforming user agents. [DataURL].

8.6.1.4. The readAsArrayBuffer method

When the readAsArrayBuffer(blob) method is called, the following steps must be followed:

  1. If readyState = LOADING throw an InvalidStateError exception [DOM4] and terminate these steps.

    Note: The method returns due to the algorithm being terminated.

  2. If the blob has been neutered through the close method, throw an InvalidStateError exception [DOM4] and terminate this algorithm.

    Note: The method returns due to the algorithm being terminated.

  3. Otherwise, initiate a read operation using the blob argument, and with the synchronous flag set. If the read operation returns failure, throw the appropriate exception. Terminate this algorithm.

  4. If no error has occurred, return the result of the read operation as an ArrayBuffer [TypedArrays].

9. Errors and Exceptions

Error conditions can occur when reading files from the underlying filesystem. The list below of potential error conditions is informative.

  • The File or Blob being accessed may not exist at the time one of the asynchronous read methods or synchronous read methods are called. This may be due to it having been moved or deleted after a reference to it was acquired (e.g. concurrent modification with another application). See NotFoundError

  • A File or Blob may be unreadable. This may be due to permission problems that occur after a reference to a File or Blob has been acquired (e.g. concurrent lock with another application). Additionally, the snapshot state may have changed. See NotReadableError

  • User agents MAY determine that some files are unsafe for use within Web applications. A file may change on disk since the original file selection, thus resulting in an invalid read. Additionally, some file and directory structures may be considered restricted by the underlying filesystem; attempts to read from them may be considered a security violation. See the security considerations. See SecurityError

9.1. Throwing an Exception or Returning an Error

This section is normative. Error conditions can arise when reading a file.

Synchronous read methods throw exceptions of the type in the table below if there has been an error with reading.

The error attribute of the FileReader object must return a DOMError object [DOM4] of the most appropriate type from the table below if there has been an error, and otherwise returns null.

Type Description
NotFoundError If the File or Blob resource could not be found at the time the read was processed, then for asynchronous read methods the error attribute must return a "NotFoundError" DOMError and synchronous read methods must throw a NotFoundError exception.
SecurityError If:
  • it is determined that certain files are unsafe for access within a Web application
  • it is determined that too many read calls are being made on File or Blob resources
  • it is determined that the file has changed on disk since the user selected it

then for asynchronous read methods the error attribute may return a "SecurityError" DOMError and synchronous read methods may throw a SecurityError exception.

This is a security error to be used in situations not covered by any other exception type.

NotReadableError If the snapshot state of a File or a Blob does not match the state of the underlying storage, then for asynchronous read methods the error attribute must return a "NotReadableError" DOMError and synchronous read methods must throw a NotReadableError exception. If the File or Blob cannot be read, typically due due to permission problems that occur after a snapshot state has been established (e.g. concurrent lock on the underlying storage with another application) then for asynchronous read methods the error attribute must return a "NotReadableError" DOMError and synchronous read methods must throw a NotReadableError exception.

10. A URL for Blob and File reference

This section defines a scheme for a URL used to refer to Blob objects (and File objects).

10.1. Requirements for a New Scheme

This specification defines a scheme with URLs of the sort: blob:550e8400-e29b-41d4-a716-446655440000#aboutABBA. This section provides some requirements and is an informative discussion.

  • This scheme should be able to be used with web APIs such as XMLHttpRequest [XHR], and with elements that are designed to be used with HTTP URLs, such as the img element [HTML]. In general, this scheme should be designed to be used wherever URLs can be used on the web.

    This scheme should have defined response codes, so that web applications can respond to scenarios where the resource is not found, or raises an error, etc.

  • This scheme should have an origin policy and a lifetime stipulation, to allow safe access to binary data from web applications.

    URLs in this scheme should be used as a references to "in-memory" Blobs, and also be re-used elsewhere on the platform to refer to binary resources (e.g. for video-conferencing [WebRTC]). URLs in this scheme are designed for impermanence, since they will be typically used to access "in memory" resources.

  • Developers should have the ability to revoke URLs in this scheme, so that they no longer refer to Blob objects. This includes scenarios where file references are no longer needed by a program, but also other uses of Blob objects. Consider a scenario where a Blob object can be exported from a drawing program which uses the canvas element and API [HTML]. A snapshot of the drawing can be created by exporting a Blob. This scheme can be used with the img [HTML] element to display the snapshot; if the user deletes the snapshot, any reference to the snapshot in memory via a URL should be invalid, and hence the need to be able to revoke such a URL.

10.2. Discussion of Existing Schemes

This section is an informative discussion of existing schemes that may have been repurposed or reused for the use cases for URLs above, and justification for why a new scheme is considered preferable. These schemes include HTTP [RFC2616], file [RFC1630][RFC1738], and a scheme such as urn:uuid [RFC4122]. One broad consideration in determining what scheme to use is providing something with intuitive appeal to web developers.

  • HTTP could be repurposed for the use cases mentioned above; it already comes with well-defined request-response semantics that are already used by web applications. But Blob resources are typically "in-memory" resident (e.g. after a file has been read into memory), and are thus unlike "traditional" HTTP resources that are dereferenced via DNS. While some user agents automatically "proxy" the underlying file system on the local machine via an HTTP server (e.g. with URLs of the sort http://localhost), HTTP is not traditionally used with local resources. Moreover, an important use case for these URLs are that they can be revoked with an API call. HTTP URLs have traditionally been used for resources that may be more permanent (and that are certainly not chiefly memory-resident, such as files that a web application can read). Reusing the HTTP scheme might be confusing for web developers owing to well-established practice.

  • The reuse of file URLs would involve changes to file URL use today, such as adding response codes. While they are used inconsistently in web applications, the structure of the URLs would change, and request-response behavior would have to be superimposed on what already works in a more-or-less ad-hoc manner. Modifying this for the use cases cited above is imprudent, given legacy usage. Additionally, the use cases for a Blob URL scheme call for uses beyond the file system.

  • A scheme of the sort urn:uuid [RFC4122] could be used, though use of this scheme is unprecedented in HTML and JavaScript web applications. The urn:uuid scheme is very generic. URLs in the scheme urn:uuid have the disadvantage of unfamiliarity and inconsistency across the web platform. A new scheme has the advantage of being explicit about what is being referenced. In theory, URLs make no guarantee about what sort of resource is obtained when they are dereferenced; that is left to content labeling and media type. But in practice, the name of the scheme creates an expectation about both the resource and the protocol of the request-response transaction. Choosing a name that clarifies the primary use case - namely, access to memory-resident Blob resources - is a worthwhile compromise, and favors clarity, familiarity, and consistency across the web platform.

10.3. The blob URL

A blob: URL must consist of the blob: scheme and an opaque string as scheme data, along with an optional fragment.

A fragment, if used, has a distinct interpretation depending on the media type of the Blob or File resource in question (see fragment discussion).

10.3.1. Origin of Blob URLs

Blob URLs are created using URL.createObjectURL or URL.createFor, and are revoked using URL.revokeObjectURL. The origin of a Blob URL must be the same as the effective script origin specified by the incumbent settings object at the time the method that created it -- either URL.createObjectURL or URL.createFor -- was called.

10.3.2. The Opaque String

An opaque string is a unique string which can be heuristically generated upon demand such that the probability that two are alike is small, and which is hard to guess (e.g. the Universally Unique IDentifier -- UUID -- as defined in [RFC4122] is an opaque string). Opaque strings must NOT include any reserved characters from [RFC3986] without percent-encoding them. Opaque strings must be globally unique. Such strings should only use characters in the ranges U+002A to U+002B, U+002D to U+002E, U+0030 to U+0039, U+0041 to U+005A, U+005E to U+007E [Unicode], and should be at least 36 characters long. UUID is one potential option available to user agents for use with Blob URLs as opaque strings, and their use is strongly encouraged. UUIDs are defined in [RFC4122]. For an ABNF of UUID, see Appendix A.

10.3.3 Discussion of Fragment Identifier

The fragment's resolution and processing directives depend on the media type [RFC2046] of a potentially retrieved representation, even though such a retrieval is only performed if the blob: URL is dereferenced. For example, in an HTML file [HTML] the fragment could be used to refer to an anchor within the file. If the user agent does not recognize the media type of the resource, OR if a fragment is not meaningful within the resource, it must ignore the fragment. The fragment must not be used to identify a resource; only the blob: scheme and the opaque string scheme data constitute a valid resource identifier.

A valid Blob URL reference could look like: blob:550e8400-e29b-41d4-a716-446655440000#aboutABBA where "#aboutABBA" might be an HTML fragment identifier referring to an element with an id attribute of "aboutABBA".

Note

The blob: scheme identifier and the opaque string as scheme data together consist of the unique identifier for a Blob or File resource. The fragment is not used to identify the resource.

10.4. Dereferencing Model for Blob URLs

The URL Specification [URL] along with the Fetch Specification [Fetch] define how Blob URLs are dereferenced. This section provides guidance on request and response headers.

User agents must only support requests with GET [RFC2616]. Specifically, responses must only support a subset of responses that are equivalent to the following from HTTP [RFC2616]:

10.4.1. 200 OK

This response [RFC2616] must be used if the request has succeeded, and no network errors are generated.

10.4.2. Response Headers

Along with 200 OK responses, user agents must use a Content-Type header [RFC2616] that is equal to the value of the Blob's type attribute, if it is not the empty string.

Along with 200 OK responses, user agents must use a Content-Length header [RFC2616] that is equal to the value of the Blob's size attribute.

If a Content-Type header [RFC2616] is provided, then user agents should obtain and process that media type in a manner consistent with the Mime Sniffing specification [MIMESNIFF].

If a resource identified with a blob: URL is a File object, user agents must use that file's name attribute, as if the response had a Content-Disposition header with the filename parameter set to the File's name attribute [RFC6266].

Note

A corollary to this is a non-normative implementation guideline: that the "File Save As" user interface in user agents takes into account the File's name attribute if presenting a default name to save the file as.

10.4.3. Network Errors

Responses that do not succeed with a 200 OK must act as if a network error has occurred [XHR]. Network errors must be used when:

10.4.4. Sample Request and Response Headers

This section provides sample exchanges between web applications and user agents using the blob: protocol. A request can be triggered using HTML markup of the sort <img src="blob:550e8400-e29b-41d4-a716-446655440000">, after a web application calls URL.createObjectURL on a given blob, which returns blob:550e8400-e29b-41d4-a716-446655440000 to dereference that blob. These examples merely illustrate the protocol; web developers are not likely to interact with all the headers, but the getAllResponseHeaders() method of XMLHttpRequest, if used, will show relevant response headers [XHR].

Example

Requests could look like this:

HEADERS

  GET 550e8400-e29b-41d4-a716-446655440000
  

If the blob has an affiliated media type [RFC2046] represented by its type attribute, then the response message should include the Content-Type header from RFC2616 [RFC2616]. See processing media types.

HEADERS

  
  200 OK
  Content-Type: image/jpeg
  Content-Length: 21897
  
  ....
  

If there is a file error or any other kind of error associated with the blob, then a user agent must act as if a network error has occurred.

10.5. Creating and Revoking a Blob URL

Blob URLs are created and revoked using methods exposed on the URL object, supported by global objects Window [HTML] and WorkerGlobalScope [Web Workers]. Revocation of a Blob URL decouples the Blob URL from the resource it refers to, and if it is dereferenced after it is revoked, user agents must act as if a network error has occurred. This section describes a supplemental interface to the URL specification [URL API] and presents methods for Blob URL creation and revocation.

IDL


partial interface URL {

  static DOMString createObjectURL(Blob blob);
  static DOMString createFor(Blob blob);
  static void revokeObjectURL(DOMString url);

};

  

ECMAScript user agents of this specification must ensure that they do not expose a prototype property on the URL interface object unless the user agent also implements the URL [URL API] specification. In other words, URL.prototype must evaluate to true if the user agent implements the URL [URL API] specification, and must NOT evaluate to true otherwise.

10.5.1. Methods and Parameters

The createObjectURL static method

Returns a unique Blob URL. This method must act as follows:

  1. If called with a Blob argument that has a readability state of CLOSED, user agents must return a unique Blob URL that has the following properties:

  2. Otherwise, user agents must run the following sub-steps:

    1. Return a unique Blob URL that can be used to dereference the blob argument and has the following properties:
    2. Add an entry to the Blob URL Store for this Blob URL.
The createFor static method

Returns a unique Blob URL; Blob URLs created with this method are said to be auto-revoking since user-agents are responsible for the revocation of Blob URLs created with this method, subject to the lifetime stipulation for Blob URLs. This method must act as follows:

  1. If called with a Blob argument that has a readability state of CLOSED, user agents must return a unique Blob URL that has the following properties:

  2. Otherwise, user agents must run the following steps:

    1. Return a unique Blob URL that can be used to dereference the blob argument and has the following properties:
    2. Add an entry to the Blob URL Store for this Blob URL.
    3. Add an entry to the Revocation List for this Blob URL.
Example

In the example below, after obtaining a reference to a Blob object (in this case, a user-selected File from the underlying file system), the static method URL.createObjectURL() is called on that Blob object.

ECMAScript

  var file = document.getElementById('file').files[0];
  if(file){
    blobURLref = window.URL.createObjectURL(file);
    myimg.src = blobURLref;

    ....

  }
  
The revokeObjectURL static method

Revokes the Blob URL provided in the string url by removing the corresponding entry from the Blob URL Store. This method must act as follows:

  1. If the url refers to a Blob that has a readability state of CLOSED OR if the value provided for the url argument is not a Blob URL, OR if the value provided for the url argument does not have an identifier in the Blob URL Store, this method call does nothing. User agents may display a message on the error console.
  2. Otherwise, user agents must remove the entry from the Blob URL Store for the identifier associated with the url argument; subsequent attempts to dereference this URL must return a network error response code.

The url argument to the revokeObjectURL method is a Blob URL string.

Example

In the example below, window1 and window2 are separate, but in the same origin; window2 could be an iframe [HTML] inside window1.

ECMAScript

  myurl = window1.URL.createObjectURL(myblob);
  window2.URL.revokeObjectURL(myurl);
  

Since window1 and window2 are in the same origin and share the same Blob URL Store, the URL.revokeObjectURL call ensures that subsequent dereferencing of myurl results in a the user agent acting as if a network error has occurred.

10.5.2. Examples of Blob URL Creation and Revocation

Blob URLs are strings that dereference Blob objects, and can persist for as long as the document from which they were minted using URL.createObjectURL() - see Lifetime of Blob URLs.

This section gives sample usage of creation and revocation of Blob URLs with explanations.

Examples

In the example below, two img elements [HTML] refer to the same Blob URL:

ECMAScript

<script>url = URL.createObjectURL(blob); </script><script> img2.src=url;</script>

In the example below, URL.revokeObjectURL() is explicitly called.

ECMAScript

var blobURLref = URL.createObjectURL(file);
img1 = new Image();
img2 = new Image();

// Both assignments below work as expected

img1.src = blobURLref;
img2.src = blobURLref;

// ... Following body load
// Check if both images have loaded


if(img1.complete && img2.complete)
{
  // Ensure that subsequent refs throw an exception
  
  URL.revokeObjectURL(blobURLref);
}
else {

  msg("Images cannot be previewed!");
  
  // revoke the string-based reference
  
  URL.revokeObjectURL(blobURLref);

}

The example above allows multiple references to a single Blob URL, and the web developer then revokes the Blob URL string after both image objects have been loaded. While not restricting number of uses of the Blob URL offers more flexibility, it increases the likelihood of leaks; developers should pair it with a corresponding call to URL.revokeObjectURL.

ECMAScript

var blobURLref2 = URL.createFor(file);
img1 = new Image();

img1.src = blobURLref2;

....

The example above uses URL.createFor, which allows uses such as the one above, and obviates the need for a corresponding call by the web developer to URL.revokeObjectURL.

ECMAScript

// file is an HTML file
// One of the anchor identifiers in file is "#applicationInfo"

var blobURLAnchorRef = URL.createFor(file) + "#applicationInfo";

// openPopup is an utility function to open a small informational window

var windowRef = openPopup(blobURLAnchorRef, "Application Info");


....

The example above uses URL.createFor to mint a Blob URL identifier for a file resource, and appends a fragment that has an understood meaning within the resource (in this case, it references an anchor within the HTML document).

10.6. Lifetime of Blob URLs

Each unit of similar origin browsing contexts [HTML] must maintain a Blob URL Store which is a list of identifiers created by the URL.createObjectURL method or the URL.createFor method, and the blob resource that each identifier refers to.

Each unit of related similar origin browsing contexts must maintain a Revocation List which is a list of identifiers that have been created with the URL.createFor method, and the blob resource that each identifier refers to.

When this specification says to add an entry to the Blob URL Store the user-agent must add the identifier created using URL.createObjectURL or URL.createFor, and a reference to the blob it refers to, to the Blob URL Store.

When this specification says to add an entry to the The Revocation List, user agents must add the identifier of any Blob URL created with the URL.createFor method to the Revocation List. This is only for auto-revoking Blob URLs.

When this specification says to remove an entry from the Blob URL Store for a given identifier or for a given Blob, user agents must remove the identifier and the blob it refers to from the Blob URL Store. Subsequent attempts to dereference this URL must result in a network error.

The Revocation List and the Blob URL Store must be processed together as follows:

  1. Add removing the entries for all the identifiers in the Revocation List to the global script cleanup jobs list
  2. When all the identifiers in the Revocation List have had their corresponding entries in the Blob URL Store removed, remove all the identifiers in the Revocation List.

  3. This specification adds an additional unloading document cleanup step [HTML]: user agents must remove all identifiers from the Blob URL Store within that document. If these identifiers are dereferenced, user agents must respond with a network error.

Note

User agents are free to garbage collect resources removed from the Blob URL Store.

11. Security Considerations

This section is informative.

This specification allows web content to read files from the underlying file system, as well as provides a means for files to be accessed by unique identifiers, and as such is subject to some security considerations. This specification also assumes that the primary user interaction is with the <input type="file"/> element of HTML forms [HTML], and that all files that are being read by FileReader objects have first been selected by the user. Important security considerations include preventing malicious file selection attacks (selection looping), preventing access to system-sensitive files, and guarding against modifications of files on disk after a selection has taken place.

  • Preventing selection looping. During file selection, a user may be bombarded with the file picker associated with <input type="file"/> (in a "must choose" loop that forces selection before the file picker is dismissed) and a user agent may prevent file access to any selections by making the FileList object returned be of size 0.

  • System-sensitive files (e.g. files in /usr/bin, password files, and other native operating system executables) typically should not be exposed to web content, and should not be accessed via Blob URLs. User agents may throw a SecurityError exception for synchronous read methods, or return a SecurityError DOMError for asynchronous reads.

  • Cross-origin requests on Blob URLs occur when a Blob URL is accessed across origins. User agents must act as if a network error has occurred if such requests are made.

Editorial note

This section is provisional; more security data may supplement this in subsequent drafts.

12. Requirements and Use Cases

This section covers what the requirements are for this API, as well as illustrates some use cases. This version of the API does not satisfy all use cases; subsequent versions may elect to address these.

  • Once a user has given permission, user agents should provide the ability to read and parse data directly from a local file programmatically.

    • Example: A lyrics viewer. User wants to read song lyrics from songs in his plist file. User browses for plist file. File is opened, read, parsed, and presented to the user as a sortable, actionable list within a web application. User can select songs to fetch lyrics. User uses the "browse for file" dialog.
  • Data should be able to be stored locally so that it is available for later use, which is useful for offline data access for web applications.

    • Example: A Calendar App. User's company has a calendar. User wants to sync local events to company calendar, marked as "busy" slots (without leaking personal info). User browses for file and selects it. The text/calendar file is parsed in the browser, allowing the user to merge the files to one calendar view. The user wants to then save the file back to his local calendar file. (using "Save As" ?). The user can also send the integrated calendar file back to the server calendar store asynchronously.
  • User agents should provide the ability to save a local file programmatically given an amount of data and a file name.

    • Example: A Spreadsheet App. User interacts with a form, and generates some input. The form then generates a CSV (Comma Separated Variables) output for the user to import into a spreadsheet, and uses "Save...". The generated output can also be directly integrated into a web-based spreadsheet, and uploaded asynchronously.
  • User agents should provide a streamlined programmatic ability to send data from a file to a remote server that works more efficiently than form-based uploads today

    • Example: A Video/Photo Upload App. User is able to select large files for upload, which can then be "chunk-transfered" to the server.
  • User agents should provide an API exposed to script that exposes the features above. The user is notified by UI anytime interaction with the file system takes place, giving the user full ability to cancel or abort the transaction. The user is notified of any file selections, and can cancel these. No invocations to these APIs occur silently without user intervention.

13. Appendix A

This section is informative, and uses the Augmented Backus-Naur Form (ABNF), defined in [RFC5234] to describe components of blob: URLs.

13.1. An ABNF for Blob URLs

ABNF

  blob = scheme ":" opaqueString [fragIdentifier]

  scheme = "blob"

  ; scheme is always "blob"

  ; opaqueString tokens must be globally unique
  ; opaqueString could be a UUID in its canonical form

  

13.2. An ABNF for UUID

The following is an informative ABNF [ABNF] for UUID, which is a strongly encouraged choice for the opaqueString production of Blob URLs.

ABNF

	UUID                   = time-low "-" time-mid "-"
	                         time-high-and-version "-"
	                         clock-seq-and-reserved
	                         clock-seq-low "-" node
	time-low               = 4hexOctet
	time-mid               = 2hexOctet
	time-high-and-version  = 2hexOctet
	clock-seq-and-reserved = hexOctet
	clock-seq-low          = hexOctet
	node                   = 6hexOctet
	hexOctet               = hexDigit hexDigit
	hexDigit =
	         "0" / "1" / "2" / "3" / "4" / "5" / "6" / "7" / "8" / "9" /
	         "a" / "b" / "c" / "d" / "e" / "f" /
	         "A" / "B" / "C" / "D" / "E" / "F"

	

13.3 An ABNF for Fragment Identifiers

ABNF

  fragIdentifier = "#" fragment

  ; Fragment Identifiers depend on the media type of the Blob
  ; fragment is defined in [RFC3986]
  ; fragment processing for HTML is defined in [HTML]

  fragment    = *( pchar / "/" / "?" )

  pchar       = unreserved / pct-encoded / sub-delims / ":" / "@"

  unreserved    = ALPHA / DIGIT / "-" / "." / "_" / "~"

  pct-encoded   = "%" HEXDIG HEXDIG

  sub-delims    = "!" / "$" / "&" / "'" / "(" / ")"
                   / "*" / "+" / "," / ";" / "="
  

14. Acknowledgements

This specification was originally developed by the SVG Working Group. Many thanks to Mark Baker and Anne van Kesteren for their feedback.

Thanks to Robin Berjon for editing the original specification.

Special thanks to Olli Pettay, Nikunj Mehta, Garrett Smith, Aaron Boodman, Michael Nordman, Jian Li, Dmitry Titov, Ian Hickson, Darin Fisher, Sam Weinig, Adrian Bateman and Julian Reschke.

Thanks to the W3C WebApps WG, and to participants on the public-webapps@w3.org listserv

15. References

15.1. Normative references

RFC2119
Key words for use in RFCs to Indicate Requirement Levels, S. Bradner. IETF.
HTML
HTML 5.1 Nightly: A vocabulary and associated APIs for HTML and XHTML (work in progress), I. Hickson. W3C.
ProgressEvents
Progress Events, A. van Kesteren. W3C.
RFC2397
The "data" URL Scheme, L. Masinter. IETF.
Web Workers
Web Workers (work in progress), I. Hickson. W3C.
DOM4
DOM4 (work in progress), A. Gregor, A. van Kesteren, Ms2ger. W3C.
Unicode
The Unicode Standard, Version 5.2.0., J. D. Allen, D. Anderson, et al. Unicode Consortium.
RFC2616
Hypertext Transfer Protocol -- HTTP/1.1, R. Fielding, J. Gettys, J. Mogul, H. Frystyk, L. Masinter, P. Leach, T. Berners-Lee. IETF.
RFC2046
Multipurpose Internet Mail Extensions (MIME) Part Two: Media Extensions, N. Freed, N. Borenstein. IETF.
RFC6266
Use of the Content-Disposition Header Field in the Hypertext Transfer Protocol (HTTP), J. Reschke. IETF.
Encoding Specification
Encoding Living Standard, A. van Kesteren, J. Bell.
Typed Arrays
Typed Arrays (work in progress), V. Vukicevic, K. Russell. Khronos Group.
RFC5234
Augmented BNF for Syntax Specifications: ABNF, D. Crocker, P. Overell. IETF.
URL Specification
URL Living Standard (work in progress), A. van Kesteren.
Fetch Specification
Fetch Specification, A. van Kesteren. WHATWG.
WebIDL Specification
WebIDL (work in progress), C. McCormack.
ECMAScript
ECMAScript 5th Edition, A. Wirfs-Brock, P. Lakshman et al.
MIME Sniffing
MIME Sniffing (work in progress), A. Barth, I. Hickson.
XMLHttpRequest
XMLHttpRequest Living Standard, A. van Kesteren.

15.2. Informative References

Google Gears Blob API
Google Gears Blob API (deprecated)
RFC4122
A Universally Unique IDentifier (UUID) URN Namespace, P. Leach, M. Mealling, R. Salz. IETF.
RFC3986
Uniform Resource Identifier (URI): Generic Syntax, T. Berners-Lee, R. Fielding, L. Masinter. IETF.
RFC1630
Universal Resource Identifiers in WWW, T. Berners-Lee. IETF.
RFC1738
Uniform Resource Locators (URL), T. Berners-Lee, L. Masinter, M. McCahill. IETF.
WebRTC 1.0
WebRTC 1.0, A. Bergkvist, D. Burnett, C. Jennings, A. Narayanan. W3C.