How to Validate Media Uploads in JavaScript

Christian Nwamba

Validation has become an essential concept in software development and the security of an application. We often run tests for vulnerability using validation on input fields. There are different types of validation in software development; this tutorial will focus on media files, validating the file extension, the number of files to be uploaded, and the file size.

Setup

We will be using the live-server dependency for our development to aid with live-reload capability. Run the command below to install the dependency globally.

1npm install -g live-server

Navigate to the project folder and create an index.html file. paste the code below in the index.html

1<!DOCTYPE html>
2<html lang="en">
3 <head>
4 <meta charset="UTF-8" />
5 <meta http-equiv="X-UA-Compatible" content="IE=edge" />
6 <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7 <title>Validate File Uploads</title>
8 <script src="https://cdn.tailwindcss.com"></script>
9 </head>
10<body>
11 <main class="flex justify-center h-screen items-center">
12 <div class="flex flex-col justify-center">
13 <input class="hidden" type="file" multiple name="filePicker" />
14 <p class="text-red-500 mb-4" id="error"></p>
15 <p class="text-green-500 mb-4" id="success"></p>
16 <div class="grid place-items-center">
17 <button class="text-white bg-gray-700 hover:bg-gray-600 px-6 py-2 rounded">
18 Upload
19 </button>
20 </div>
21 </div>
22 </main>
23<script src="./index.js"></script>
24</body>
25</html>

Create A List of Allowed Image and Video Types

Create an index.js file at the root of the project and paste the code below.

1const videoMimeTypes = [
2 'video/x-flv',
3 'video/x-ms-wmv',
4 'video/x-msvideo',
5 'video/quicktime',
6 'video/3gpp',
7 'video/MP2T',
8 'application/x-mpegURL',
9 'video/mp4',
10];
11
12const imageMimeTypes = [
13 'image/webp',
14 'image/tiff',
15 'image/svg+xml',
16 'image/png',
17 'image/jpeg',
18 'image/vnd.microsoft.icon',
19 'image/gif',
20 'image/bmp',
21];

The code above are the mime types where we add our extension types for images and videos. These types are the list of allowed types that can be uploaded.

Grab DOM Elements

Before writing our validation functions, create an onload function to confirm that the page is done loading before running the javascript code.

1window.onload = function validation() {
2 //our code will be here
3}

Our codes will be nested within the onload function.

Create javascript variables to point to the HTML tags using the querySelector. Paste the code below inside the onload function.

1const filePicker = document.querySelector('input');
2const button = document.querySelector('button');
3const errorParagraph = document.querySelector('#error');
4const successParagraph = document.querySelector('#success');

Handle Upload

Next is to implement an onClick on the upload button. The function below will execute once we click on the upload button. It triggers the filePicker function, which is attached to a change listener. The change event is triggered when we upload a file.

1button.addEventListener('click', () => {
2 if (filePicker) filePicker.click();
3});
4
5filePicker.addEventListener('change', (e) => {
6 const files = e.target.files;
7 console.log(files);
8
9// validation functions here
10
11});

Write Validation Functions

Once we drop the file in the browser, we need to start validating it. Here are the function signature of the validation we need to write:

1function validateSize(file, max)
2function validateExtension(file, allowedExtensions = [])
3function validateLength(files, max)
4function updateErrorMessage(el, message)
5function updateSuccessMessage(el, message)

Each of these functions has a vital role in validating our file upload.

  • validateSize: handles the uploaded file size.
  • validateExtension: handles the file extension of the uploaded file as listed in our mime types.
  • validateLength: handles the number of files we can upload at once.

We will be showing the code behind each of these functions as we go further. We will first start with the validateSize function, which validates the size of our file in Megabyte.

1function validateSize(file, max) {
2 return file.size <= max;
3}

Next is the validateExtension funtion, which ****validates the type of extensions allowed.

1function validateExtension(file, allowedExtensions = []) {
2 return allowedExtensions.includes(file.type);
3}

Next is the validateLength, which validates that the total number of files uploaded at once is valid.

1function validateLength(file, max){
2 return file.length <= max;
3}

Error Message Functions

We can also have a few functions to display our error and success messages.

1function updateErrorMessage(el, message) {
2 el.innerText = message;
3 console.warn(message);
4}
5function updateSuccessMessage(el, message) {
6 el.innerText = message;
7 console.log(message);
8}

Validate the Files

Now that we have defined our validation, error, and success function, we will head back to the filepicker change handle to start our conditions for validation using the functions. We will start by validating only length. To validate only the length paste the code below in the change listener.

1if (!validateLength(files, 3)) {
2 updateErrorMessage(errorParagraph, 'Number of files must not exceed 3.');
3} else {
4 updateSuccessMessage(successParagraph, 'All files passed validation!');
5}

To validate length and extensions of our files paste the code below.

1if (!validateLength(files, 3)) {
2 updateErrorMessage(errorParagraph, 'Number of files must not exceed 3.');
3} else {
4 for (f of files) {
5 if (!validateExtension(f, [...imageMimeTypes, ...videoMimeTypes])) {
6 updateErrorMessage(
7 errorParagraph,
8 `${f.name} is neither an image or a video.`
9 );
10 break;
11 }
12 updateSuccessMessage(successParagraph, 'All files passed validation!');
13 }
14}

To validate the size, length, and extension of every uploaded file, paste the code below.

1if (!validateLength(files, 3)) {
2 updateErrorMessage(errorParagraph, 'Number of files must not exceed 3.');
3} else {
4 for (f of files) {
5 if (!validateExtension(f, [...imageMimeTypes, ...videoMimeTypes])) {
6 updateErrorMessage(
7 errorParagraph,
8 `${f.name} is neither an image or a video.`
9 );
10 break;
11 }
12 if (!validateSize(f, 1024 ** 2 * 2)) {
13 updateErrorMessage(
14 errorParagraph,
15 `${f.name}'s size exceeds 2 Megabytes`
16 );
17 break;
18 }
19 updateSuccessMessage(successParagraph, 'All files passed validation!');
20 }
21}

Conclusion

In this tutorial, we have discussed and shown how easy it is to validate media files making it easier to protect our applications from unwanted and irrelevant files that may disrupt the performance of our application. The complete source code for this tutorial is available on CodeSandbox.

Christian Nwamba

Developer Advocate at AWS

A software engineer and developer advocate. I love to research and talk about web technologies and how to delight customers with them.