How to handle file uploads with the FileReader API
Read files from the browser's clipboard or input elements, convert them to base64 or text, and send them to a server endpoint securely without blocking the main thread.
Read files directly from the browser's local storage using the FileReader API. You will learn to convert uploaded files into text or base64 strings and send them to a server endpoint. These steps target modern browsers supporting the standard File API and Fetch API.
Prerequisites
- A modern browser (Chrome 10+, Firefox 5+, Safari 5+, Edge 12+) with JavaScript enabled.
- A local development server running (e.g., Node.js with http-server or PHP built-in server).
- A basic understanding of DOM events like
changeandload. - Access to a file input element or a file path in your code.
Step 1: Create the file input element
Add an HTML <input> element to your page to allow users to select files. Set the accept attribute to restrict file types, such as images or text files. This element triggers the change event when a user selects a file.
<input type="file" id="fileInput" accept=".txt,.jpg,.png" />
You will see the input appear in your browser window. The accept attribute filters the file picker to show only supported types.
Step 2: Initialize the FileReader object
Create a new FileReader instance to handle the file reading process. Assign it to a variable so you can reuse it or create multiple readers for different files. This object provides methods like readAsDataURL and readAsText.
const fileReader = new FileReader();
The variable fileReader is now ready to read files. You will configure its event listeners in the next step.
Step 3: Define the onload event handler
Set the onload property of the FileReader object to a function that runs when reading completes. Inside this function, access the result property to get the file content as a Data URL or text string. Use console.log to inspect the result in the browser console.
fileReader.onload = function(event) {
const fileData = event.target.result;
console.log("File read successfully:", fileData);
};
You will see the file content logged to the console once the read operation finishes. The result contains the full file data.
Step 4: Define the onerror event handler
Set the onerror property to handle failures during the read operation. Common errors include invalid file paths or permission issues. Log the error message to the console to debug issues.
fileReader.onerror = function(event) {
console.error("Error reading file:", event.target.error);
};
Testing with an invalid file path will trigger this handler. You will see the error details in the console.
Step 5: Read the file using readAsDataURL
Add an event listener for the change event on the file input element. Inside the handler, check if a file is selected using the files property. Call readAsDataURL on the FileReader object with the selected file as the argument.
document.getElementById('fileInput').addEventListener('change', function(event) {
const file = event.target.files[0];
if (file) {
fileReader.readAsDataURL(file);
}
});
When a user selects a file, the reader starts immediately. You will see the Data URL appear in the console.
Step 6: Read the file using readAsText
Repeat the process but use readAsText instead of readAsDataURL for text files. This method returns the file content as a plain string. Ensure the file encoding is compatible with the browser's default encoding.
const textReader = new FileReader();
textReader.onload = function(event) {
const textContent = event.target.result;
console.log("File content:", textContent);
};
textReader.readAsText(file);
The console will display the raw text content of the file. This is useful for log files or configuration files.
Step 7: Upload the file to a server
Create a FormData object to attach the file to a network request. Use the fetch API to send the data to your server endpoint. Include the Content-Type header set to multipart/form-data automatically by fetch.
const formData = new FormData();
formData.append('file', file);
fetch('/upload', {
method: 'POST',
body: formData
})
.then(response => response.json())
.then(data => console.log('Upload successful:', data))
.catch(error => console.error('Upload failed:', error));
The server receives the file in the request body. You will see the upload status in the response JSON.
Verify the installation
Open your browser's developer tools and navigate to the Console tab. Select a file using the input element. You will see the file content logged to the console. Check the Network tab to confirm the POST request was sent with the correct headers.
// Expected console output after selecting a file:
// File read successfully: data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA...
If the console shows the file data and the Network tab shows a 200 status code, your setup is correct. No additional installation is required for the API itself.
Troubleshooting
If the file does not load, check the browser console for errors. Ensure the file input has the accept attribute set correctly. Verify that the server endpoint accepts multipart/form-data requests. If using readAsText, confirm the file is not binary or encoded in a format the browser cannot interpret.
// Common error message:
// TypeError: Failed to execute 'readAsText' on 'FileReader': The file is not a valid text file.
Resolve this by using readAsDataURL for binary files or ensuring the file is plain text. For large files, consider implementing progress tracking using the onprogress event on the FileReader object to monitor upload status.
fileReader.onprogress = function(event) {
const percentComplete = (event.loaded / event.total) * 100;
console.log(`Upload progress: ${percentComplete.toFixed(2)}%`);
};
Use this to display a progress bar in your UI. If the file path is invalid, the onerror handler will catch it. Always validate the file size before reading to avoid memory issues with very large files.