Explain Codes LogoExplain Codes Logo

How to check file MIME type with JavaScript before upload?

javascript
file-signature
mime-type-validation
file-upload
Nikita BarsukovbyNikita Barsukov·Jan 6, 2025
TLDR

Get an immediate check of a file's MIME type with JavaScript by using the change event of a file input. The File object in the files array of the input has a type property that holds the MIME type. Use this property to validate your file, as shown below:

document.querySelector('#fileInput').addEventListener('change', function(e) { let fileType = e.target.files[0].type; if (fileType === 'image/jpeg' || fileType === 'image/png') { console.log('Valid image file:', fileType); } else { console.log('Invalid file type:', fileType); } });

The code above checks whether the selected file is a JPEG or PNG image. This way, you can ensure before uploading that the file is of the desired type. Customize the fileType checks as needed according to your specific requirements.

Type property? It's just the start!

The type property represents a quick yet not always reliable method of checking MIME types. To ensure accuracy and security, we recommend performing further validation.

Perform MIME Magic with File Signatures

For enhanced security, validate the file's MIME type by inspecting its content—specifically, its file signature—over the extension. This approach compares the file's header to magic numbers, which are distinct identifiers for different file types.

function getMIMEType(file) { return new Promise((resolve, reject) => { const reader = new FileReader(); reader.onloadend = function(e) { const arr = (new Uint8Array(e.target.result)).subarray(0, 4); let header = ""; for(let i = 0; i < arr.length; i++) { header += arr[i].toString(16); } switch (header) { case "89504e47": resolve("image/png"); break; case "ffd8ffe0": // because JPEGs are too hipster to settle on one magic number case "ffd8ffe1": case "ffd8ffe2": resolve("image/jpeg"); break; default: resolve("unknown"); break; } }; reader.readAsArrayBuffer(file.slice(0, 4)); }); }

The above script extracts the first four bytes of the file, creating a more precise determination of the MIME type.

Lighten the Load: Efficiency on the Front-End

Reading only a portion of a file cuts down the memory consumption, avoiding browser freezes and enriching the user experience by reducing the waiting time.

Shoring Up on Browser Compatibility and Accessibility

Be sure to verify browser support for the File and Blob APIs with resources like "Can I Use". Think about incorporating information messages and accessibility features to keep users in the loop about the status of their file.

Curate your MIME Pattern Database

Create a local database of MIME patterns for durable, front-end file validations. Expand your repertoire of MIME patterns from references available, such as the W3C spec and MIME Sniffing standards.

Callbacks and TypeScript Interfaces

Incorporate callback functions for the flexible handling of MIME type check results. If you're using TypeScript, bring interfaces into play to help enforce the structure of file signature pattern matching.

Handling Remote Files

For dealing with remote files, have your backend do the heavy lifting—downloading the file bytes—which can then be vetified client-side in a similar manner.