# Uploading files on the server using Fetch API

By Atta Ur Rehman Shah (https://attacomsian.com/about). Published Aug 15, 2019, updated Jun 10, 2023. Topics: JavaScript.
Canonical URL: https://attacomsian.com/blog/uploading-files-using-fetch-api

> A step-by-step guide to upload upload files on server using JavaScript Fetch API. Example code snippets for handling server side requests using Node.js and Spring Boot.

File uploading is a commonly used feature in modern web applications. While there are many JavaScript libraries available to handle file uploads efficiently, you can achieve the same functionality using native JavaScript with the help of the [Fetch API](https://attacomsian.com/blog/javascript-fetch-api), a promise-based alternative to XHR for making HTTP requests in the browser.

## Fetch API file upload

To handle file uploads using the Fetch API in native JavaScript, follow these steps:

1. Add the following HTML input element to your website:

```markup
<input type="file" id="avatar">
```

2. Attach an event listener to the input element that will be triggered when a file is selected by the user:

```javascript
// Select the file input
const input = document.getElementById('avatar');

// Add an event listener
input.addEventListener('change', () => {
  uploadFile(input.files[0]);
});
```

3. Implement the `uploadFile()` method, which takes a `File` object as input and uploads it to the server using `fetch()` and the [`FormData`](https://attacomsian.com/blog/javascript-formdata) interface:

```javascript
const uploadFile = file => {
  // Add the file to the FormData object
  const fd = new FormData();
  fd.append('avatar', file);

  // Send a POST request
  fetch('/upload-avatar', {
    method: 'POST',
    body: fd
  })
    .then(res => res.json())
    .then(json => console.log(json))
    .catch(err => console.error(err));
};
```

> **Note:** Do not set the `Content-Type` header for a multipart request when using `fetch()`. The browser will automatically add the necessary content type header, including the form boundary.

## Validate file type & size

You can also perform validation on the file properties, such as file type and size, before initiating the upload:

```javascript
const uploadFile = file => {
  // Check the file type
  if (!['image/jpeg', 'image/gif', 'image/png', 'image/svg+xml'].includes(file.type)) {
    console.log('Only images are allowed.');
    return;
  }

  // Check the file size (< 2MB)
  if (file.size > 2 * 1024 * 1024) {
    console.log('File must be less than 2MB.');
    return;
  }

  // ...
};
```

## Uploading file to the server using Node.js

Below is an example that handles the file upload request in Node.js. It utilizes the `express-fileupload` library, a simple Express middleware for handling file uploads. This library parses `multipart/form-data` requests, extracts the files (if available), and makes them accessible through the `req.files` property:

```javascript
app.post('/upload-avatar', async (req, res) => {
  try {
    if (!req.files) {
      res.send({
        status: false,
        message: 'No file uploaded'
      });
    } else {
      // Use the name of the input field (i.e., "avatar") to retrieve the uploaded file
      let avatar = req.files.avatar;

      // Use the mv() method to store the file in the upload directory (e.g., "uploads")
      avatar.mv('./uploads/' + avatar.name);

      // Send the response
      res.send({
        status: true,
        message: 'File uploaded',
        data: {
          name: avatar.name,
          mimetype: avatar.mimetype,
          size: avatar.size
        }
      });
    }
  } catch (err) {
    res.status(500).send(err);
  }
});
```

Refer to the [this guide](https://attacomsian.com/blog/uploading-files-nodejs-express) guide to learn more about handling files in Node.js.

 uploads in Node.js.

## Uploading file to the server using Spring Boot

If you are using Spring Boot for the backend, the following code snippet demonstrates how to handle the file upload request in Spring Boot:

```java
@PostMapping("/upload-avatar")
@ResponseBody
public ResponseEntity<String> fileUpload(MultipartFile avatar) {
    try {

        // upload directory - change it to your own
        String UPLOAD_DIR = "/opt/uploads";

        // create a path from the file name
        Path path = Paths.get(UPLOAD_DIR, avatar.getOriginalFilename());

        // save the file to `UPLOAD_DIR`
        // make sure you have permission to write
        Files.write(path, avatar.getBytes());
    }
    catch (Exception ex) {
        ex.printStackTrace();
        return new ResponseEntity<>("Invalid file format!!", HttpStatus.BAD_REQUEST);
    }

    return new ResponseEntity<>("File uploaded!!", HttpStatus.OK);
}
```

For handling single and multiple file uploads in a Spring Boot application, refer to the [this guide](https://attacomsian.com/blog/uploading-files-spring-boot).
