How to get the file extension in Node.js from the MIME type

By

Learn how to get a file extension in Node.js from its name with path.extname() or from a MIME type using mime.extension() from the mime-types package.

~~~

You have two ways to get a file extension in Node.js: parse the file name with path.extname(), or look up the MIME type with the mime-types package. Let’s see both, starting from the problem that got me here.

I was sending a file through a form, and after using a form with multipart/form-data, server-side I had the File objects in req.files.

This gave me some information, like the path, name, size, type and so on:

{
  logo: File {
    size: 121920,
    path: '/var/folders/tn/h8lfq1sj7c33c0p30qgkd3mw0000gn/T/upload_b9e85b7cf989482a1760d82b77fd555a',
    name: 'Screen Shot 2021-06-07 at 21.40.29.png',
    type: 'image/png',
    hash: null,
    lastModifiedDate: 2021-06-07T22:20:50.150Z,
//...
  }
}

Notice the temp file path does not have an extension.

If you use the name server-side, no problem. But I wanted to change it and use my own naming conventions, so I needed just the file extension.

Option 1: parse the file name

The path module is built into Node, so this does not require any 3rd party library:

const path = require('path')
path.extname(req.files.logo.name) //.png

Note that the result includes the dot.

There are a couple of edge cases worth knowing:

path.extname('archive.tar.gz') //.gz
path.extname('.gitignore') //''
path.extname('README') //''

Only the last part after the final dot counts, dotfiles are not treated as extensions, and a file without a dot returns an empty string.

Option 2: use the MIME type

Alternatively, you can use the mime-types package and get the extension from the MIME type:

const mime = require('mime-types')
mime.extension('text/plain') //txt
mime.extension('image/png') //png

Here the result does not include the dot. And if the MIME type is unknown, you get false back, so check the return value before using it.

The package also works in the other direction, from name to MIME type:

mime.lookup('invoice.pdf') //application/pdf

One warning

The MIME type in an upload comes from the browser, and the file name comes from the user. Both can be faked.

They are fine for picking a name or an extension, like I did here. Don’t rely on them to decide if a file is safe to process. Validate the actual content server-side for that.

Tagged: Node.js · All topics
~~~

Related posts about node: