0% found this document useful (0 votes)
103 views

Using Files From Web Applications - Web APIs - MDN

The document discusses how to access and obtain information about files selected by the user through the browser's file picker using the File API. It covers selecting files, accessing the file list, getting metadata like the file name and size, and displaying the total size of selected files. It also provides an example of hiding the file input element and triggering the file picker with a click.

Uploaded by

xi si
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
103 views

Using Files From Web Applications - Web APIs - MDN

The document discusses how to access and obtain information about files selected by the user through the browser's file picker using the File API. It covers selecting files, accessing the file list, getting metadata like the file name and size, and displaying the total size of selected files. It also provides an example of hiding the file input element and triggering the file picker with a click.

Uploaded by

xi si
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 17

Sign in

English ▼

Using files from web applications

Using the File API, which was added to the DOM in HTML5, it's now possible for web content
to ask the user to select local files and then read the contents of those files. This selection can
be done by either using an HTML <input type="file"> element or by drag and drop.

If you want to use the DOM File API from extensions or other browser chrome code, you can;
however, note there are some additional features to be aware of. See Using the DOM File API
in chrome code for details.

Accessing selected file(s)


Consider this HTML:

1 <input type
type=
="file
file"" id
id=
="input
input"" multiple
multiple>
>

The File API makes it possible to access a FileList containing File objects representing
the files selected by the user.

The multiple attribute on the input element allows the user to select multiple files.

Accessing the first selected file using a classical DOM selector:

1 const selectedFile = document


document..getElementById
getElementById(('input'
'input')).files
files[[0];

Accessing selected file(s) on a change event


It is also possible (but not mandatory) to access the FileList through the change event.
You need to use EventTarget.addEventListener() to add the change event listener,
like this:
1 const inputElement = document
document..getElementById
getElementById(("input"
"input"));
2 inputElement..addEventListener
inputElement addEventListener(("change"
"change",, handleFiles
handleFiles,, false
false));
3 function handleFiles
handleFiles(() {
4 const fileList = this
this..files
files;; /* now you can work with the file list */
5 }

Getting information about selected file(s)


The FileList object provided by the DOM lists all of the files selected by the user, each
specified as a File object. You can determine how many files the user selected by checking
the value of the file list's length attribute:

1 const numFiles = fileList


fileList..length
length;;

Individual File objects can be retrieved by simply accessing the list as an array:

1 for (let i = 0, numFiles = fileList


fileList..length
length;; i < numFiles
numFiles;; ii++
++)) {
2 const file = fileList[
fileList[i];
3 // ...
4 }

This loop iterates over all the files in the file list.

There are three attributes provided by the File object that contain useful information about
the file.

name
The file's name as a read-only string. This is just the file name, and does not include any
path information.

size
The size of the file in bytes as a read-only 64-bit integer.

type
The MIME type of the file as a read-only string or "" if the type couldn't be determined.
Example: Showing file(s) size
The following example shows a possible use of the size property:

1 <!DOCTYPE html>
2 <html
html> >
3 <head
head> >
4 <meta charset
charset=="UTF-8
UTF-8"">
5 <title
title>
>File(s) size</
size</title
title>
>
6 <script
script>>
7 function updateSize
updateSize(() {
8 let nBytes = 0,
9 oFiles = this
this..files
files,,
10 nFiles = oFiles
oFiles..length
length;;
11 for (let nFileId = 0; nFileId < nFilesnFiles;; nFileId
nFileId++
++)) {
12 nBytes += oFiles
oFiles[[nFileId
nFileId]].size
size;;
13 }
14 let sOutput = nBytes + " bytes";bytes";
15 // optional code for multiples approximation
16 const aMultiples = ["KiB""KiB",, "MiB"
"MiB",, "GiB"
"GiB",, "TiB"
"TiB",, "PiB"
"PiB",, "EiB"
"EiB",, "ZiB"
"ZiB",, "YiB"
"YiB"]];
17 for (nMultiple = 0, nApprox = nBytes / 1024 1024;; nApprox > 1; nApprox /= 1024 1024,, nMultiple
18 sOutput = nApprox
nApprox..toFixed
toFixed((3) + " " + aMultiples
aMultiples[[nMultiple
nMultiple]] + " (" + nBytes + " bytes
19 }
20 // end of optional code
21 document..getElementById
document getElementById(("fileNum"
"fileNum")).innerHTML = nFiles nFiles;;
22 document..getElementById
document getElementById(("fileSize"
"fileSize")).innerHTML = sOutput
sOutput;;
23 }
24
25 document.getElementById
document. getElementById(("uploadInput"
"uploadInput")).addEventListener
addEventListener(("change"
"change",, updateSize
updateSize,, false
26 </script
</script>
>
27 </head
</head>>
28
29 <body
body>>
30 <form name
name=
="uploadForm
uploadForm"">
31 <div
div>
>
32 <input idid=
="uploadInput
uploadInput"" type
type= ="file
file"" name
name=
="myFiles
myFiles"" multiple
multiple>
>
33 selected files: <span id
id=="fileNum
fileNum"">0</ </span
span>
>;
34 total size: <span id
id=
="fileSize
fileSize"">0</
</span
span>
>
35 </div
</div>
>
36 <div
div>
><input type
type=
="submit
submit"" value
value=
="Send file"
file"></
</div
div>
>
37 </form
</form>>
38
39 </body
</body>
>
</html
</html>
>

Using hidden file input elements using the click() method


You can hide the admittedly ugly file <input> element and present your own interface for
opening the file picker and displaying which file or files the user has selected. You can do this
by styling the input element with display:none and calling the click() method on the
<input> element.

Consider this HTML:

1 <input type
type=="file
file"" id
id=
="fileElem
fileElem"" multiple accept
accept=
="image/*
image/*"" style
style="
="display
display::none
none"">
2 <button id
id=
="fileSelect
fileSelect"">Select some files</
files</button
button>
>

The code that handles the click event can look like this:

1 const fileSelect = document


document..getElementById
getElementById(("fileSelect"
"fileSelect")),
2 fileElem = document
document..getElementById
getElementById(("fileElem"
"fileElem"));
3
4 fileSelect.addEventListener
fileSelect. addEventListener(("click"
"click",, function (e) {
5 if (fileElem
fileElem)) {
6 fileElem..click
fileElem click(();
7 }
8 }, false
false));

You can style the new button for opening the file picker as you wish.

Using a label element to trigger a hidden file input element


To allow opening the file picker without using JavaScript (the click() method), a <label>
element can be used. Note that in this case the input element must not be hidden using
display: none (nor visibility: hidden ), otherwise the label would not be keyboard-
accessible. Use the visually-hidden technique instead.

Consider this HTML:

1 <input type
type=
="file
file"" id
id=
="fileElem
fileElem"" multiple accept
accept=="image/*
image/*"" class
class=
="visually-hidden
visually-hidden"">
2 <label for
for=
="fileElem
fileElem"">Select some files</
files</label
label>
>

and this CSS:

1 .visually-hidden {
2 position:: absolute !important
position !important;;
3 height:: 1px
height px;;
4 width:: 1px
width px;;
5 overflow:: hidden
overflow hidden;;
6 clip:: rect
clip rect((1px
px,, 1px
px,, 1px
px,, 1px
px));
7 }
8
9 /* Separate rule for compatibility, :focus-within is required on modern Firefox and Chrom
10 input.visually-hidden
input .visually-hidden:focus
:focus + label {
11 outline:: thin dotted;
outline dotted;
12 }
13 input.visually-hidden
input .visually-hidden:focus-within
:focus-within + label {
14 outline:: thin dotted;
outline dotted;
15 }

There is no need to add JavaScript code to call fileElem.click() . Also in this case you
can style the label element as you wish. You need to provide a visual cue for the focus status of
the hidden input field on its label, be it an outline as shown above, or background-color or box-
shadow. (As of time of writing, Firefox doesn’t show this visual cue for <input
type="file"> elements.)

Selecting files using drag and drop


You can also let the user drag and drop files into your web application.
The first step is to establish a drop zone. Exactly what part of your content will accept drops
may vary depending on the design of your application, but making an element receive drop
events is easy:

1 let dropbox
dropbox;;
2
3 dropbox = document
document..getElementById
getElementById(("dropbox"
"dropbox"));
4 dropbox.addEventListener
dropbox. addEventListener(("dragenter"
"dragenter",, dragenter
dragenter,, false
false));
5 dropbox..addEventListener
dropbox addEventListener(("dragover"
"dragover",, dragover
dragover,, false
false));
6 dropbox..addEventListener
dropbox addEventListener(("drop"
"drop",, drop
drop,, false
false));

In this example, we're turning the element with the ID dropbox into our drop zone. This is
done by adding listeners for the dragenter , dragover , and drop events.

We don't actually need to do anything with the dragenter and dragover events in our case,
so these functions are both simple. They just stop propagation of the event and prevent the
default action from occurring:

1 function dragenter
dragenter((e) {
2 e..stopPropagation
e stopPropagation(();
3 e..preventDefault
e preventDefault(();
4 }
5
6 function dragover
dragover((e) {
7 e..stopPropagation
e stopPropagation(();
8 e..preventDefault
e preventDefault(();
9 }

The real magic happens in the drop() function:

1 function drop
drop((e) {
2 e.stopPropagation
e. stopPropagation(();
3 e..preventDefault
e preventDefault(();
4
5 const dt = ee..dataTransfer
dataTransfer;;
6 const files = dt
dt..files
files;;
7
8 handleFiles((files
handleFiles files));
9 }
Here, we retrieve the dataTransfer field from the event, pull the file list out of it, and then
pass that to handleFiles() . From this point on, handling the files is the same whether the
user used the input element or drag and drop.

Example: Showing thumbnails of user-selected images


Let's say you're developing the next great photo-sharing website and want to use HTML to
display thumbnail previews of images before the user actually uploads them. You can establish
your input element or drop zone as discussed previously and have them call a function such as
the handleFiles() function below.

1 function handleFiles
handleFiles((files
files)) {
2 for (let i = 0; i < files
files..length
length;; ii++
++)) {
3 const file = files
files[[i];
4
5 if (!file
file..type
type..startsWith
startsWith(('image/'
'image/'))){ continue }
6
7 const img = document
document..createElement
createElement(("img"
"img"));
8 img..classList
img classList..add
add(("obj"
"obj"));
9 img..file = file
img file;;
10 preview..appendChild
preview appendChild((imgimg)); // Assuming that "preview" is the div output where the co
11
12 const reader = new FileReader
FileReader(();
13 reader..onload = (function
reader function((aImg
aImg)) { return function
function((e) { aImg
aImg..src = e
e..target
target..result
result;; };
14 reader..readAsDataURL
reader readAsDataURL((file
file));
15 }
16 }

Here our loop handling the user-selected files looks at each file's type attribute to see if its
MIME type begins with the string " image/ "). For each file that is an image, we create a new
img element. CSS can be used to establish any pretty borders or shadows and to specify the
size of the image, so that doesn't need to be done here.

Each image has the CSS class obj added to it, making it easy to find in the DOM tree. We
also add a file attribute to each image specifying the File for the image; this will let us
fetch the images for actual upload later. We use Node.appendChild() to add the new
thumbnail to the preview area of our document.
Next, we establish the FileReader to handle asynchronously loading the image and
attaching it to the img element. After creating the new FileReader object, we set up its
onload function and then call readAsDataURL() to start the read operation in the
background. When the entire contents of the image file are loaded, they are converted into a
data: URL which is passed to the onload callback. Our implementation of this routine sets
the img element's src attribute to the loaded image which results in the image appearing in
the thumbnail on the user's screen.

Using object URLs


The DOM URL.createObjectURL() and URL.revokeObjectURL() methods let you
create simple URL strings that can be used to reference any data that can be referred to using
a DOM File object, including local files on the user's computer.

When you have a File object you'd like to reference by URL from HTML, you can create an
object URL for it like this:

1 const objectURL = window


window..URL
URL..createObjectURL
createObjectURL((fileObj
fileObj));

The object URL is a string identifying the File object. Each time you call
URL.createObjectURL() , a unique object URL is created even if you've created an object
URL for that file already. Each of these must be released. While they are released automatically
when the document is unloaded, if your page uses them dynamically you should release them
explicitly by calling URL.revokeObjectURL() :

1 URL..revokeObjectURL
URL revokeObjectURL((objectURL
objectURL));

Example: Using object URLs to display images


This example uses object URLs to display image thumbnails. In addition, it displays other file
information including their names and sizes.

The HTML that presents the interface looks like this:


1 <input type
type=
="file
file"" id
id=
="fileElem
fileElem"" multiple accept
accept=
="image/*
image/*"" style
style="
="display
display::none
none"">
2 <a href
href=="#" idid=
="fileSelect
fileSelect"">Select some files</
files</a
a>
3 <div id
id=
="fileList
fileList"">
4 <p>No files selected!</
selected!</p p>
5 </div
</div>
>

This establishes our file <input> element as well as a link that invokes the file picker (since
we keep the file input hidden to prevent that less-than-attractive user interface from being
displayed). This is explained in the section Using hidden file input elements using the click()
method,, as is the method that invokes the file picker.
method

The handleFiles() method follows:

1 const fileSelect = document


document..getElementById
getElementById(("fileSelect"
"fileSelect")),
2 fileElem = document
document..getElementById
getElementById(("fileElem"
"fileElem")),
3 fileList = document
document..getElementById
getElementById(("fileList"
"fileList"));
4
5 fileSelect.addEventListener
fileSelect. addEventListener(("click"
"click",, function (e) {
6 if (fileElem
fileElem)) {
7 fileElem..click
fileElem click(();
8 }
9 e..preventDefault
e preventDefault((); // prevent navigation to "#"
10 }, false
false));
11
12 fileElem..addEventListener
fileElem addEventListener(("change"
"change",, handleFiles
handleFiles,, false
false));
13
14 function handleFiles
handleFiles(() {
15 if (!this
this..files
files..length
length)) {
16 fileList..innerHTML = "<p>No files selected!</p>";
fileList selected!</p>";
17 } else {
18 fileList.innerHTML = ""
fileList. "";;
19 const list = document
document..createElement
createElement(("ul""ul"));
20 fileList..appendChild
fileList appendChild((list
list));
21 for (let i = 0; i < this
this..files
files..length
length;; ii++
++)) {
22 const li = document
document..createElement
createElement(("li"
"li"));
23 list..appendChild
list appendChild((li
li));
24
25 const img = document
document..createElement
createElement(("img"
"img"));
26 img..src = URL
img URL..createObjectURL
createObjectURL((this
this..files
files[[i]);
27 img..height = 60
img 60;;
28 img..onload = function
img function(() {
URL..revokeObjectURL
URL revokeObjectURL((this
this..src
src));
29 }
30 li..appendChild
li appendChild((img
img));
31 const info = document
document..createElement
createElement(("span"
"span"));
32 info..innerHTML = this
info this..files
files[[i].name + ": " + this
this..files
files[[i].size + " bytes";
bytes";
33 li..appendChild
li appendChild((info
info));
34 }
35 }
36 }
37

This starts by fetching the URL of the <div> with the ID fileList . This is the block into
which we'll insert our file list, including thumbnails.

If the FileList object passed to handleFiles() is null , we simply set the inner HTML of
the block to display "No files selected!". Otherwise, we start building our file list, as follows:

1. A new unordered list ( <ul> ) element is created.


2. The new list element is inserted into the <div> block by calling its
Node.appendChild() method.
3. For each File in the FileList represented by files :

1. Create a new list item ( <li> ) element and insert it into the list.
2. Create a new image ( <img> ) element.
3. Set the image's source to a new object URL representing the file, using
URL.createObjectURL() to create the blob URL.
4. Set the image's height to 60 pixels.
5. Set up the image's load event handler to release the object URL since it's no longer
needed once the image has been loaded. This is done by calling the
URL.revokeObjectURL() method and passing in the object URL string as
specified by img.src .

6. Append the new list item to the list.

Here is a live demo of the code above:


23.gif: 1347010 bytes

01.gif: 2091658 bytes

08.gif: 1139611 bytes

31.gif: 977822 bytes

25.gif: 1438848 bytes

Example: Uploading a user-selected file


Another thing you might want to do is let the user upload the selected file or files (such as the
images selected using the previous example) to a server. This can be done asynchronously
very easily.

Creating the upload tasks


Continuing with the code that built the thumbnails in the previous example, recall that every
thumbnail image is in the CSS class obj with the corresponding File attached in a file
attribute. This allows us to select all of the images the user has chosen for uploading using
Document.querySelectorAll() , like this:

1 function sendFiles
sendFiles(() {
2 const imgs = document
document..querySelectorAll
querySelectorAll((".obj"
".obj"));
3
4 for (let i = 0; i < imgs
imgs..length
length;; ii++
++)) {
5 new FileUpload
FileUpload((imgs
imgs[[i], imgs
imgs[[i].file
file));
6 }
7 }
Line 2 fetches a NodeList , called imgs , of all the elements in the document with the CSS
class obj . In our case, these will be all of the image thumbnails. Once we have that list, it's
trivial to go through it and create a new FileUpload instance for each. Each of these handles
uploading the corresponding file.

Handling the upload process for a file


The FileUpload function accepts two inputs: an image element and a file from which to read
the image data.

1 function FileUpload
FileUpload((img
img,, file
file)) {
2 const reader = new FileReader
FileReader(();
3 this..ctrl = createThrobber
this createThrobber((imgimg));
4 const xhr = new XMLHttpRequest
XMLHttpRequest(();
5 this..xhr = xhr
this xhr;;
6
7 const self = thisthis;;
8 this..xhr
this xhr..upload
upload..addEventListener
addEventListener(("progress"
"progress",, function
function((e) {
9 if (e.lengthComputable
lengthComputable)) {
10 const percentage = Math Math..round
round(((e.loaded * 100
100)) / e
e..total
total));
11 self..ctrl
self ctrl..update
update((percentage
percentage));
12 }
13 }, false
false));
14
15 xhr..upload
xhr upload..addEventListener
addEventListener(("load""load",, function
function((e){
16 self..ctrl
self ctrl..update
update((100
100));
17 const canvas = self self..ctrl
ctrl..ctx
ctx..canvas
canvas;;
18 canvas..parentNode
canvas parentNode..removeChild
removeChild((canvas
canvas));
19 }, false
false));
20 xhr..open
xhr open(("POST"
"POST",, "http://demos.hacks.mozilla.org/paul/demos/resources/webservices/
21 xhr..overrideMimeType
xhr overrideMimeType(('text/plain; charset=x-user-defined-binary')
charset=x-user-defined-binary');
22 reader..onload = function
reader function((evt
evt)) {
23 xhr..send
xhr send((evt
evt..target
target..result
result));
24 };
25 reader..readAsBinaryString
reader readAsBinaryString((file
file));
26 }

The FileUpload() function shown above creates a throbber, which is used to display
progress information, and then creates an XMLHttpRequest to handle uploading the data.

Before actually transferring the data, several preparatory steps are taken:
1. The XMLHttpRequest 's upload progress listener is set to update the throbber with
new percentage information so that as the upload progresses the throbber will be
updated based on the latest information.
2. The XMLHttpRequest 's upload load event handler is set to update the throbber
progress information to 100% to ensure the progress indicator actually reaches 100% (in
case of granularity quirks during the process). It then removes the throbber since it's no
longer needed. This causes the throbber to disappear once the upload is complete.
3. The request to upload the image file is opened by calling XMLHttpRequest 's open()
method to start generating a POST request.
4. The MIME type for the upload is set by calling the XMLHttpRequest function
overrideMimeType() . In this case, we're using a generic MIME type; you may or may
not need to set the MIME type at all depending on your use case.
5. The FileReader object is used to convert the file to a binary string.

6. Finally, when the content is loaded the XMLHttpRequest function send() is called to
upload the file's content.

Asynchronously handling the file upload process


This example, which uses PHP on the server side and JavaScript on the client side,
demonstrates asynchronous uploading of a file.

1 <?php
2 if (isset
isset(($_FILES
$_FILES[['myFile'
'myFile']])) {
3 // Example:
4 move_uploaded_file(($_FILES
move_uploaded_file $_FILES[['myFile'
'myFile']]['tmp_name'
'tmp_name']], "uploads/" . $_FILES
$_FILES[['myFile'
'myFile']]['n
5 exit;;
exit
6 }
7 ?><!DOCTYPE html html>>
8 <html
html>>
9 <head
head>>
10 <title
title>
>dnd binary upload<
upload</title
title>
>
11 <meta http-
http-equiv
equiv=
="Content-Type" content
content=
="text/html; charset=UTF-8">
charset=UTF-8">
12 <script type=
type="application/javascript"
"application/javascript">
>
13 function sendFile
sendFile((file
file)) {
14 const uri = "/index.php"
"/index.php";;
15 const xhr = new XMLHttpRequest
XMLHttpRequest(();
16 const fd = new FormData
FormData(();
17
18 xhr.open
xhr. open(("POST"
"POST",, uri
uri,, true
true));
19 xhr..onreadystatechange = function
xhr function(() {
20 if (xhr
xhr..readyState == 4 && xhr xhr..status == 200
200)) {
21 alert((xhr
alert xhr..responseText
responseText)); // handle response.
22 }
23 };
24 fd..append
fd append(('myFile'
'myFile',, file
file));
25 // Initiate a multipart/form-data upload
26 xhr..send
xhr send((fd
fd));
27 }
28
29 window..onload = function
window function(() {
30 const dropzone = document
document..getElementById
getElementById(("dropzone"
"dropzone"));
31 dropzone..ondragover = dropzone
dropzone dropzone..ondragenter = function
function((event
event)) {
32 event..stopPropagation
event stopPropagation(();
33 event..preventDefault
event preventDefault(();
34 }
35
36 dropzone..ondrop = function
dropzone function((event
event)) {
37 event.stopPropagation
event. stopPropagation(();
38 event..preventDefault
event preventDefault(();
39
40 const filesArray = event
event..dataTransfer
dataTransfer..files
files;;
41 for (let ii=
=0; ii<
<filesArray
filesArray..length
length;; ii++
++)) {
42 sendFile((filesArray
sendFile filesArray[[i]);
43 }
44 }
45 }
46 </script
script>
>
47 </head
head>>
48 <body
body>>
49 <div
div>
>
50 <div id=
id="dropzone" style
style=
="margin:30px; width:500px; height:300px; border:1px
51 </div
div>
>
52 </body
body>>
53 </html
html>
>

Example: Using object URLs to display PDF


Object URLs can be used for other things than just images! They can be used to display
embedded PDF files or any other resources that can be displayed by the browser.
In Firefox, to have the PDF appear embedded in the iframe (rather than proposed as a
downloaded file), the preference pdfjs.disabled must be set to false .

1 <iframe id
id=
="viewer
viewer"">

And here is the change of the src attribute:

1 const obj_url = URL


URL..createObjectURL
createObjectURL((blob
blob));
2 const iframe = document
document..getElementById
getElementById(('viewer'
'viewer'));
3 iframe..setAttribute
iframe setAttribute(('src'
'src',, obj_url
obj_url));
4 URL..revokeObjectURL
URL revokeObjectURL((obj_url
obj_url));

Example: Using object URLs with other file types


You can manipulate files of other formats the same way. Here is how to preview uploaded
video:

1 const video = document


document..getElementById
getElementById(('video'
'video'));
2 const obj_url = URL
URL..createObjectURL
createObjectURL((blob
blob));
3 video..src = obj_url
video obj_url;;
4 video..play
video play(();
5 URL..revokeObjectURL
URL revokeObjectURL((obj_url
obj_url));

Specifications
Specification Status Comment

HTML Living Standard


LS Living Standard
The definition of 'File upload state' in that specification.

File API WD Working Draft Initial definition


See also
File
FileList
FileReader

URL
XMLHttpRequest
Using XMLHttpRequest

Last modified: Mar 29, 2020,


2020, by MDN contributors

Related Topics
File

▼ Constructor

File()

▼ Properties

fileName

fileSize

lastModified

lastModifiedDate

mozFullPath

name

type

webkitRelativePath

▼ Methods

getAsBinary()

getAsDataURL()
getAsText()

▼ Inheritance:

Blob

▼ Related pages for File API

Blob

FileList

FileReader

FileReaderSync

Learn the best of web development


Get the latest and greatest from MDN delivered straight to your inbox.

you@example.com

Sign up now

You might also like