The HTML5 File API provides browsers with the ability to interact with files on the user’s computer, allowing web applications to process file data directly on the client side without relying on the server to upload and process it. This enhances the functionality and user experience of web applications, especially for those scenarios that need to process user-uploaded files (such as pictures, documents, videos, etc.).
Core Objects
FileList Object
The FileList object is an array-like read-only list that represents a set of files selected by the user through the <input type="file"> element. Each file is a File object stored in the FileList. This list can be accessed through the files attribute of the HTML element:
<input type="file" multiple onchange="handleFiles(this.files)">function handleFiles(files) {
for (let i = 0; i < files.length; i++) {
console.log(files[i].name);
}
}File Object
The File object represents a single user-selected file, providing the following key properties:
name: The name of the file, excluding the path.type: The MIME type of the file, such asimage/jpeg.size: The size of the file in bytes.lastModified: The time the file was last modified on the user’s system, in milliseconds.
In addition, the File object also inherits from the Blob object, so you can use the slice() method to create parts or copies of files, as well as use ArrayBuffer, TextDecoder, etc. to read binary or text data.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>File Object Example</title>
</head>
<body>
<input type="file" id="fileInput" multiple>
<button id="analyzeFilesButton">Analyze Files</button>
<script>
document.getElementById('analyzeFilesButton').addEventListener('click', function() {
const fileInput = document.getElementById('fileInput');
const files = fileInput.files;
if (files.length > 0) {
for (let i = 0; i < files.length; i++) {
const file = files[i];
analyzeFile(file);
}
} else {
console.log('No files selected.');
}
});
function analyzeFile(file) {
console.group(`File: ${file.name}`);
console.log('Type:', file.type);
console.log('Size:', file.size, 'bytes');
console.log('Last modified:', new Date(file.lastModified));
console.groupEnd();
}
</script>
</body>
</html>File information reading
FileReader interface
To read file contents, HTML5 provides the FileReader interface. It has the following reading modes:
readAsArrayBuffer(file): Reads the file as anArrayBuffer, suitable for processing binary data.readAsDataURL(file): Reads the file as a Data URL string, which can be directly used as the source of elements such as<img>and<video>.readAsText(file, [encoding]): Reads the file as a text string, and the encoding must be specified (such as UTF-8).
FileReader provides events to track reading progress and results:
onloadstart: Triggered when reading starts.onprogress: Triggered periodically during reading, can be used to display a progress bar.onload: Triggered after successful reading, the result is saved in the result attribute.onerror: Triggered when reading fails.onabort: Triggered when reading is canceled by the abort() method.
Example:
const reader = new FileReader();
reader.onload = function(e) {
const dataURL = e.target.result;
// Update image element using dataURL
document.querySelector('img').src = dataURL;
};
reader.readAsDataURL(file);Drag and drop files
The file API is combined with the HTML5 drag and drop API to enable files to be directly dragged into the browser window for upload. By listening to the drop event, you can get the files included in the drag and drop operation:
<div id="dropzone" ondrop="handleDrop(event)" ondragover="event.preventDefault()"></div>
<script>
function handleDrop(event) {
event.preventDefault();
const files = event.dataTransfer.files;
}
</script>FileReaderSync (Workers)
In the Web Workers environment, due to the limitations of asynchronous operations, a synchronous version of the FileReaderSync interface is provided, which supports the readAsArrayBuffer(), readAsText(), and readAsDataURL() methods, but can only be used in the Worker context.
worker.js:
self.onmessage = function(e) {
const file = e.data.file;
const reader = new FileReaderSync();
try {
const text = reader.readAsText(file);
self.postMessage({ result: text });
} catch (error) {
self.postMessage({ error: error.message });
}
};main.js:
const fileInput = document.getElementById('fileInput');
fileInput.addEventListener('change', function() {
const file = fileInput.files[0];
if (file) {
const worker = new Worker('worker.js');
worker.postMessage({ file: file });
worker.onmessage = function(e) {
if (e.data.error) {
console.error('Error reading file:', e.data.error);
} else {
console.log('File content:', e.data.result);
}
};
}
});FileWriter API
Although not supported by all browsers, HTML5 also defines the FileWriter API, which allows writing directly to the user file system (such as the browser’s sandbox storage) with user permission. FileWriter provides write(), seek(), and truncate() methods, as well as corresponding events to track writing progress and results.
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>FileWriter, Blob URL & revokeObjectURL() Example</title>
</head>
<body>
<input type="file" id="fileInput">
<button id="saveButton">Save Changes</button>
<button id="downloadButton">Download Modified File</button>
<script src="file-writer-example.js"></script>
</body>
</html>file-writer-example.js:
document.getElementById('fileInput').addEventListener('change', function(e) {
const file = e.target.files[0];
const reader = new FileReader();
reader.onload = function() {
const blob = new Blob([reader.result], { type: file.type });
const objectURL = URL.createObjectURL(blob);
// Suppose we modify the blob here
// ... perform modifications on blob ...
document.getElementById('downloadButton').addEventListener('click', function() {
downloadBlob(objectURL, file.name);
});
};
reader.readAsArrayBuffer(file);
});
function downloadBlob(url, filename) {
const a = document.createElement('a');
a.href = url;
a.download = filename;
a.click();
URL.revokeObjectURL(url);
}
// Assume we have a `saveChangesToFile` function that takes a Blob object and writes it back to the original file using a FileWriter
async function saveChangesToFile(blob) {
const fileHandle = await getFileHandleFromUser(); // Implementing methods to obtain file handles
const writable = await fileHandle.createWritable();
await writable.write(blob);
await writable.close();
}Blob URL and revokeObjectURL()
The window.URL.createObjectURL(fileOrBlob) method can convert a File or Blob object into a temporary URL (Blob URL) that points to the data of the file or blob. This URL can be used inside the browser, for example, as the source of elements such as <img>, <audio>, and <video>. After use, call window.URL.revokeObjectURL(url) to release the resource.
Cross-origin resource sharing (CORS)
For some operations (such as previewing large files, directly reading file contents, etc.), the server may need to cooperate in setting CORS headers to allow cross-domain access to file data.



