File uploading is a requirement for a lot of web apps. Most of them at least need to be able to upload some pictures.
Unfortunately, out of the box neither Node nor Express supports file uploading. Moreover, it is not trivial to implement this feature from scratch.
However, there are some solutions which can help you. Let’s look at one very simple way to implement file uploading to local folder of your server.
Starting Point
Let’s assume that you have the following application structure.
It’s a classical MVC structure. Controllers contain your request handlers, models handle your data and business logic, and views define all page templates. Public contains all publicly accessible static files like images, front-end JavaScript and stylesheets.
In this example, you are going to upload files to the public/uploads/
folder.
Initially your pictures.js controller looks like this.
It has only one request handler, which handles all POST requests to pictures/upload. This is where you will handle your files.
However, before you go further with the file handling let’s first create a simple form which is capable of sending files from the browser to your server. You should place the following snippet of HTML when you need file upload.
It uploads files directly to pictures/upload just where you expect them. Moreover
it has the following attribute enctype="multipart/form-data"
. Without it, your form
will not be able to upload files to the server.
There is just one more thing to have in mind. You have put the name image to your input element of type file. Remember it, you will see in a minute why it is important.
For the actual file uploading you are going to use one additional NPM module called multer. It makes file uploading to a local folder a breeze.
It has a ton of features, but my favorite one is that it automatically renames files when uploading so that there is no file collision and no file overwrites any other.
Install it with NPM.
multer is a middleware, which when it sees a post request from a form with
enctype="multipart/form-data"
understand that there is a file to be uploaded.
In your code you want only the /pictures/upload
path to handle file uploads, so
this is where you are going to use your new middleware.
Now, whenever a file is submitted from your form it is automatically saved in the public/uploads folder. This happens even before your request handler is called.
Your new middleware provides you with a few useful objects inside the request handler.
In req.files
you have access to all files uploaded with the current request.
Do you remember that you gave the name picture to the input element of type file
above? Now you can access all of its properties from req.files.picture
. Easy.
What properties you ask, well here they are:
- originalname - Name of the file on the user’s computer
- name - Renamed file name
- encoding - Encoding type of the file
- mimetype - Mime type of the file
- path - Location of the uploaded file
- extension - Extension of the file
- size - Size of the file in bytes
- truncated - If the file was truncated due to size limitation
- buffer - Raw data (is null unless the inMemory option is true)
You can use them for example to create a new record in your database for the new image. However, bare in mind, that at this point the image is already uploaded in the folder.
Limits
File uploading is cool and you can leave your code like that, but there are some potential problem. Someone could upload a 1TB file which will not only fill your entire hard drive, but it can also choke to death your entire server.
Thanks to some of the built-in features of multer, you can easily fix this problem.
With this configuration in place, you have limited to uploading at most 1 file at a time and of size no more than 1MB.
Disadvantages of local file uploading.
You want upload files, but sometimes uploading them locally is not so good idea. First and most, all hard drives have a limit. It might be 1MB, 1GB or 1TB but there is always a limit and sometimes your application should be able to store an unlimited number of files of almost any size.
Handling this is a complicated task. Moreover, even if you implement such a system, there is another serious problem. File redundancy. What if a hard disk fails? You don’t want to lose precious data.
Creating this file redundancy is hard and difficult task, too.
Advantages
The first advantage is that implementing uploading files to a local fodler is easy, just a few lines.
Then you also have very fast access to files, which especially critical if you need to do some file processsing.
When you talk about file processing, it is simpler to proces a file stored locally than one stored on a remote server.
Next
Your next step should be to learn more about multer and its other useful features.
Once you reach its limits, your next step should be learn about S3. The wonderful service by Amazon Web Services, which can handle an unlimited number of files of virtually any size.
Not only that, but once they are stored in S3 they can either be accessed programatically with very simple API or S3 can serve them directly to your users over HTTP or HTTPS. As a result all the heavy traffic will not be on your servers.
Other articles that you may like