ExpressJS – How to use express-fileupload to handle uploading files
The express-fileupload library is a middleware for Express framework that provides you with an easy way to handle file upload using the Express framework.
This tutorial will help you learn how to code an Express server that handles file upload using express-fileupload
library.
Nội Dung Chính
Handling a file upload with express-fileupload
First, you need to have both express
and express-fileupload
modules installed in your project.
npm install express express-fileupload
Once you installed the modules, create a new file named app.js
that will contain your Express server code.
Your express server will have two minimum routes:
- The index
/
route (or default route) that renders an HTML file containing a<form>
- The
/upload
route that will process file upload from its request
First, import the required modules for your server as follows:
const
express
=
require
(
"express"
);
const
fileUpload
=
require
(
"express-fileupload"
);
const
path
=
require
(
"path"
);
The path
module will be used to create a valid absolute path for saving the uploaded file later.
For now, create a new express instance by calling the express()
function:
const
app
=
express
();
Then, enable the express-fileupload
middleware by calling app.use()
method:
app
.
use
(
fileUpload
()
);
Create the index /
route that will serve an index.html
file as follows:
app
.
get
(
"/"
,
(
req
,
res
)
=>
{
res
.
sendFile
(
path
.
join
(
__dirname
,
"index.html"
));
});
Now you need to create an index.html
that will be rendered by Express when the browser sends a request to the index /
route.
The HTML file contains a <form>
element where you can upload a single file:
<!DOCTYPE html>
<
html
>
<
head
>
<
title
>
Express File Upload</
title
>
</
head
>
<
body
>
<
h1
>
Express File Upload</
h1
>
<
form
method
=
"POST"
action
=
"/upload"
enctype
=
"multipart/form-data"
>
<
input
type
=
"file"
name
=
"myFile"
/>
<
input
type
=
"submit"
/>
</
form
>
</
body
>
</
html
>
The <form>
element action
attribute will contain the Express route for receiving uploads, while the enctype
attribute is set to multipart/form-data
.
The enctype
stands for encoding type, and the multipart/form-data
type allows you to send files through an HTTP POST request.
Also, take note of the input name
attribute because you need it to retrieve the uploaded file later. The name
attribute for the file upload above is set to myFile
.
Finally, create the /upload
route that will handle file upload over a POST
request as shown below:
app
.
post
(
"/upload"
,
(
req
,
res
)
=>
{
// TODO: process the file upload
});
First, you need to check if the file is included in the request by checking if the req.files
object is defined or not.
When there’s no file uploaded, send a 400
response with "No files were uploaded."
as the message:
app
.
post
(
"/upload"
,
(
req
,
res
)
=>
{
if
(
!
req
.
files
)
{
return
res
.
status
(
400
).
send
(
"No files were uploaded."
);
}
});
When there is at least one file uploaded, you can continue to process the file by using the properties and methods provided by express-fileupload
.
Following the name
attribute of the file input above, the file you uploaded will be assigned under req.files.myFile
.
app
.
post
(
"/upload"
,
(
req
,
res
)
=>
{
if
(
!
req
.
files
)
{
return
res
.
status
(
400
).
send
(
"No files were uploaded."
);
}
const
file
=
req
.
files
.
myFile
;
});
Once you retrieved the file, it’s time to save the file on your system by using the file.mv()
method provided by the middleware.
The mv()
method will send the file from the temporary path to the path you specified as its parameter.
The method accepts two parameters:
- A
path
string where the file will be moved - A
callback
function that will be executed once the move process is finished
The method also sends the error object to the callback
function, so you can use an if
block to check if the process throws an error.
Here’s the complete code for moving the file under your system:
app
.
post
(
"/upload"
,
(
req
,
res
)
=>
{
if
(
!
req
.
files
)
{
return
res
.
status
(
400
).
send
(
"No files were uploaded."
);
}
const
file
=
req
.
files
.
myFile
;
const
path
=
__dirname
+
"/files/"
+
file
.
name
;
file
.
mv
(
path
,
(
err
)
=>
{
if
(
err
)
{
return
res
.
status
(
500
).
send
(
err
);
}
return
res
.
send
({
status
:
"success"
,
path
:
path
});
});
});
The path
of your file will be located at the files/
folder under your project directory.
With your Express server and HTML page ready, it’s time to get the server online by running node app.js
command:
node app.js
Once your Express server is online. Open your browser and head to the address to see the HTML page you’ve created previously.
When you upload a file and submit the form, an ENOENT
error will occur because the files/
folder does not exist.
Here’s an example of my error:
{
"errno"
:
-2
,
"code"
:
"ENOENT"
,
"syscall"
:
"open"
,
"path"
:
"/Users/nsebhastian/Desktop/test/files/image.png"
}
To prevent the ENOENT
error, you need to create the files/
folder manually in your project folder.
Alternatively, you can also set the createParentPath
option to true
when you call the fileUpload()
function inside app.use()
method.
The option will let express-fileupload
create the directory path for mv()
method when it doesn’t exist:
app
.
use
(
fileUpload
({
createParentPath
:
true
,
})
);
And now you should be able to upload your file just fine.
Validating file requirements with express-fileupload
You can also validate the file being send from the request by utilizing the properties addded by express-fileupload
middleware.
For example, you can check the file extension and only allow image extensions like .jpg
and .png
as shown below:
const
file
=
req
.
files
.
myFile
;
const
extensionName
=
path
.
extname
(
file
.
name
);
// fetch the file extension
const
allowedExtension
=
[
'.png'
,
'.jpg'
,
'.jpeg'
];
if
(
!
allowedExtension
.
includes
(
extensionName
)){
return
res
.
status
(
422
).
send
(
"Invalid Image"
);
}
You can also check if the uploaded file size is above a certain limit by setting the limits
option inside the fileUpload()
call.
The example below will set the file size limit to 1 MB and abort the request process by returning an HTTP 413 response when the file exceeds the limit.
app
.
use
(
fileUpload
({
limits
:
{
fileSize
:
1024
*
1024
// 1 MB
},
abortOnLimit
:
true
}));
The file size limit is set in bytes
.
Handling multiple files upload using express-fileupload
The express-fileupload
handle multiple files upload by assigning each file to the req.files
object.
Suppose you have an HTML with three file <input>
elements as follows:
<
form
method
=
"POST"
action
=
"/upload"
enctype
=
"multipart/form-data"
>
<
input
type
=
"file"
name
=
"myFile"
/>
<
input
type
=
"file"
name
=
"myPicture"
/>
<
input
type
=
"file"
name
=
"myVideo"
/>
<
input
type
=
"submit"
/>
</
form
>
You can retrieve the uploaded files from the req.files.[name]
as shown below:
app
.
post
(
"/upload"
,
(
req
,
res
)
=>
{
console
.
log
(
req
.
files
.
myFile
);
console
.
log
(
req
.
files
.
myPicture
);
console
.
log
(
req
.
files
.
myVideo
);
});
Just like in the single upload example, you need to take note of the name
attribute you used in your HTML page.
Conclusion
The express-fileupload
library is a minimalist Express framework middleware that does exactly what the name implies.
The middleware provides you with properties, methods and configurations to validate files send through a POST request and save them in your filesystem.
For more information, check out the express-fileupload Github page.