Simple Image Upload with Express
Published: 2021-06-13 14:45:27

This is a very simple basic refresher to uploading photos from a `html` form to an express server and to save it into a folder. 

### Setup the server

We'll use express to run a simple server with an api route for uploading multiple images. Since the data will be coming over as a multi-part `FormData` we'll use a middleware handler called `multer` . `multer` will take the `FormData` and parse the content to store binary files while also being able to parse out other text fields. 

```jsx
npm i express multer
```

Create a new server file called `server.js` and setup the basic foundations for an app with a `POST` route called `/upload`. We will also use `express` to render static pages from a `public` folder, where we will create a single page that has the upload form.

```jsx
const express = require("express");
const app = express();

app.use(express.static(path.join(__dirname, "public")));

// Route
app.post("/upload", function (req, res, next) {
  res.json({ 
		success: true,
		payload: [] 
	});
});

app.listen(8080, () => console.log("Server started on 8080"));
```

### Configure Multer

Next we'll configure the middleware `multer` to handle the `FormData`. Add the following to `server.js` after `const app = express()`.

```jsx
const path = require("path");
const multer = require("multer");

const storage = multer.diskStorage({
  destination: function (req, file, callback) {
    callback(null, "uploads");
  },
  filename: function (req, file, callback) {
    callback(null, file.originalname);
  },
});

const upload = multer({ storage: storage });
```

This will define the location where `multer` will store the file and to also define the file name to be the same as the existing. Realistically you would want to rename the file to have some form of unique name in case a different image with the same name is uploaded, you would not want this to overwrite the original. 

But I don't care here, this is just a basic example. Now lets incorporate `upload` into the `/upload` route. We use the `.array()` method for multiple file uploads, and pass a `String` as the first parameter that defines the field name that is being used in the `FormData` to identify the files that are being uploaded. In this example we will use "images".

```jsx
app.post("/upload", upload.array("images"), function (req, res, next) {
  res.json({
    success: true,
    payload: req.files,
  });
});
```

### Prepare the form

Inside `pubic` folder, create a new file named `index.html` and add the following code.

```jsx
<html>
  <head>
		<title>Basic Image Uploader</title>
	</head>
  <body>
    <h1>Image Uploader</h1>
    <form action="/upload" enctype="multipart/form-data" method="POST">
      <input type="file" name="images" multiple/>
      <button type="submit">Upload</button>
    </form>
  </body>
</html>
```

We are simply creating a form that has an action to `POST` the `/upload` api endpoint and to encode the data as a multi-part `FormData`. Defining the `name` attribute for the `input` field will be used for the `field` name in the `FormData`. This must be the same as the field name passed into the `upload.array()` middleware function in the `server.js` route for `/upload`.

### Test the form

Run the server by running `node server.js` and visit the url `http://localhost:8080/` to upload a file through the form. The file should end up in the project directory under the `upload` folder or whatever that was defined in the `multer` configuration.