How To Validate File Types for File Uploads in JavaScript — Front End
Sharing files is an integral part of today’s internet. Users need tools to upload their legal documents, vlog videos, and meme images. While creating a file uploader is not hard, ensuring that only the correct file types are collected is crucial to app safety and reliability. You must validate files on the front-end and back-end of your services. Let us discuss how to validate file types for uploaded files with JavaScript on the front-end.
How do User’s Upload Files?
Before we can validate user files on the front end, we need to have files to validate. Creating a file uploader may sound like a difficult task. Luckily HTML has native elements to help us get this feature implemented quickly. The HTML input element is a simple tool for getting user input like text, dates, and files.
To create our basic file uploader we add the following HTML element to our page:
<input type=“file” />
We now have a file upload element so the user can add local files:
This is as basic as the file input will be. We can add custom CSS to match our uploader to our app or site theme. We also have several attributes to expand the element’s abilities. First, the “multiple” attribute allows users to add more than one file to an input element.
Along with “multiple” is the “capture” attribute. This specifies which camera a device should use to capture input. These attributes are useful, but the attribute we are most interested in for file validation is the “accept” attribute.
How to Validate User File Uploads without JavaScript
A programming principle that will keep your site or app working is KISS (keep it simple stupid). While JavaScript extends our ability to manipulate and validate HTML and code, it is best to grab the least complicated tool for a task. This keeps our code easy to understand and less likely to have bugs.
Before we look at how to validate our user’s uploaded files with JavaScript, let’s discuss how to validate file types using HTML. The file input DOM element has an “accept” attribute that allows us to check the file types the user uploads. We can use this attribute similarly to the text validation attributes maxlength and minlength.
If we wanted to limit the file uploads to specific image files, our input element would look something like this:
<input type=“file” accept=“.png,.jpg,.jpeg,.webp,image/png” />
Accept has the value of a string containing a comma-separated list of accepted file-type extensions and types. This is a simple method to validate file input types. It is not foolproof, as users can trick this validator by modifying the file’s name to match an accepted file type.
How to Validate User File Uploads with JavaScript
We have talked about validating upload file types using HTML, but now look at how to validate using JavaScript. As we discussed previously, HTML can be good for basic validation, but there are ways to trick the client such as renaming “example.exe” to “example.jpg.” With JavaScript on the front end, we can do further checks on the file input object to ensure safety and reliability.
If we are adding JavaScript to a file input element, we will likely access the DOM element and store it in a variable. This file input DOM element has 2 keys that can be useful for us to access.
First, we have the “value” attribute which returns a string containing the path to the uploaded image. This key only works if the file input is a single upload input element. If we want to validate this element, it is easier to use the accept attribute on the file input element.
The second file input element attribute “files” is more useful for our goal of validating the file type. This key returns an object where each key is an index, and each value is an instance of a File object with the uploaded file’s data. If we were to access the file input DOM element and then the files key we would have something like this:
<script>
const fileUploader = document.getElementById('fileUploader');
fileUploader.addEventListener('change', () => {
console.log(fileUploader.value);
// C:\fakepath\myupload.png
console.log(fileUploader.files[0])
// {
// lastModified: 1709874390000,
// lastModifiedDate: DateObj,
// name: 'myupload.png'
// size: 1200120,
// type: 'image/png'
// }
});
</script>
We can see dates as seconds since 1970 and a readable date. We can also see the file size, and most importantly the file name and file type. We can run validations against both of these values to ensure that the file is the correct type:
<script>
//// File Validations /////
const validateFileType = (fileObj) => {
// Create array of good name extensions
const acceptedTypes = ['png', 'jpg', 'jpeg'];
// Create array of good types
const acceptedTypesLong = ['image/png', 'image/jpg', 'image/jpeg'];
const nameExtension = fileObj.name.split('.').pop();
// 1) Check that the name is compliant
if (!acceptedTypes.includes(nameExtension)) {
// This will remove the file from the input
fileUploader.value = null;
}
// 2) Check that the File object type is compliant
if(!acceptedTypesLong.includes(fileObj.type)) {
// This will remove the file from the input
fileUploader.value = null;
}
return true;
};
fileUploader.addEventListener('change', () => validateFileType(fileUploader.files[0]));
</script>
Notice that if the given file is not the correct type, we set the DOM elements value to null. You may see other developers set this value to an empty string. This may lead to errors across different browsers. The safest way to reset the file input on failed validation is to set the DOM element value to null.
The final point for this JavaScript front-end file validation is a best practice for validating files. With software, you should always fail early and handle the failure gracefully. When we look to validate forms, we usually wait until a user clicks “Submit” and triggers an onsubmit event.
While this works for validating text fields, we do not want the user to enter any value into a file input that may break the form or harm our back-end service. With file inputs, always validate during a change event. By adding this validation as a change event, the file will not be added to the form data unless it has a valid type
It never hurts to rerun validations on submit. However, to prevent earlier misbehavior by the user, validate the file input value on change to ensure safer, more resilient services.
Why We Need File Upload Validation on the Back End
We have added file validation for the front end of our application, but this does not fully keep our application safe from malicious actors. Our checks run when users interact with the client, preventing them from uploading unwanted file types. However, it does not protect us from direct POST calls to our back-end server.
The form HTML element has an action attribute that specifies where we send the form data and gives malicious actors an address to directly send their dangerous code. In the next file validation article we will discuss how to validate files on the back-end to complete our coverage.