Uploading files and processing them in the backend is a common functionality in web applications, such as uploading avatars or attachments. In this article, we will learn how to upload files to the server using JavaScript.
Uploading Files Client-Side
To enable file upload functionality in our web app, we start by adding an HTML file input element:
<input type="file" id="fileUpload" />
Next, we register a change handler on the #fileUpload
DOM element. When the user selects a file, we trigger the handleImageUpload()
function and pass in the selected file.
const handleImageUpload = event => {
const files = event.target.files;
const formData = new FormData();
formData.append('myFile', files[0]);
fetch('/saveImage', {
method: 'POST',
body: formData
})
.then(response => response.json())
.then(data => {
console.log(data.path);
})
.catch(error => {
console.error(error);
});
};
document.querySelector('#fileUpload').addEventListener('change', event => {
handleImageUpload(event);
});
We use the Fetch API to send the file to the server. Once the server successfully processes the file, it will return the image path in the path
property of the response. This allows us to update the interface as needed.
Handling File Upload Server-Side with Node.js
Now let’s look at the server-side implementation using Node.js with the Express framework.
First, install the express-fileupload
npm module:
npm install express-fileupload
Then, add it to your middleware:
const fileupload = require('express-fileupload');
// use it as middleware
app.use(fileupload());
Adding this middleware allows the server to parse file uploads properly. Otherwise, the req.files
object will be undefined
.
To handle file uploads, define a route for handling the /saveImage
endpoint:
app.post('/saveImage', (req, res) => {
const fileName = req.files.myFile.name;
const path = __dirname + '/images/' + fileName;
req.files.myFile.mv(path, (error) => {
if (error) {
console.error(error);
res.writeHead(500, {
'Content-Type': 'application/json'
});
res.end(JSON.stringify({ status: 'error', message: error }));
return;
}
res.writeHead(200, {
'Content-Type': 'application/json'
});
res.end(JSON.stringify({ status: 'success', path: '/img/houses/' + fileName }));
});
});
In this example, we use the mv
property of the uploaded file, which is provided by the express-fileupload
module, to move the file to the desired path. Then, we communicate either the success or an error back to the client.
Checking File Properties Client-Side
If you need to check the file type or size before uploading it, you can preprocess them in the handleImageUpload
function. Here’s an example that checks if the file is an image and its size is within the allowed limit:
const handleImageUpload = event => {
const files = event.target.files;
const myImage = files[0];
const imageType = /image.*/;
if (!myImage.type.match(imageType)) {
alert('Sorry, only images are allowed');
return;
}
if (myImage.size > (100 * 1024)) {
alert('Sorry, the max allowed size for images is 100KB');
return;
}
// ...
};
By using these techniques, you can implement file upload functionality in your web app and handle the files both on the client and server side with ease.