Skip to content

Instantly share code, notes, and snippets.

@almeidaraul
Created July 22, 2022 19:40
Show Gist options
  • Save almeidaraul/b9858bd62a4f06dac97b4a7e441f7623 to your computer and use it in GitHub Desktop.
Save almeidaraul/b9858bd62a4f06dac97b4a7e441f7623 to your computer and use it in GitHub Desktop.
How to send a file in a POST request

How to send a file from a Vue client to an Express server with a POST request

There are two steps intrinsic to a file being sent: the sender sending it off, and the receiver getting it. Let's go through that.

Vue client

Your Vue client will have a form and a function for doing something with that form. The form should look something like this:

<form v-on:submit.prevent="onSubmit" enctype="multipart/form-data">
  <input
    type="file"
    name="file"
    accept=".csv"
    @input="(event) => onUpdate(event)"
  />
  <input type="submit" value="submit" />
</form>
  • v-on:submit.prevent="onSubmit" tells Vue to execute the onSubmit function (which we'll define in a second) instead of redirecting the client to another page
  • The multipart/form-data encoding type allows you to send information besides your file
  • The @input="(event) => logger(event)" allows you to do something to the file every time it's updated

Now, to our code. These are the things we need to import and define:

import axios from "axios";
import FormData from "form-data";

let file: File;

And here's the onUpdate function, which just updates the value of file according to the newly uploaded file:

const onUpdate = async (event: any) => {
  file = await event?.target?.files[0];
};

onSubmit is more complicated. We create a FormData object which will be sent in the request and append the file to it. Then we create a config object to add the Content-Type header, which you've seen already in the HTML form, and finally send the file off with axios (remember to change the EXPRESS-SERVER-ADDRESS value).

const onSubmit = () => {
  if (!file) return;

  const formData = new FormData();
  formData.append("file", file);

  const config = { headers: { "Content-Type": "multipart/form-data" } };

  axios
    .post("EXPRESS-SERVER-ADDRESS", formData, config)
    .then((res) => console.log(res))
    .catch((err) => console.error(err));
};

Requests in axios return promises, so we can either do something with an actual response (then) or handle erros (catch).

Express server

The server is way simpler. We need a multer storage, in particular a memory storage (to save the file content to a variable - if you don't want this, read the multer documentation). Then we just assign it to a variable upon receiving the POST request from our client (in this case, I converted it to a string because the input was a CSV file - do whatever you want).

const express = require('express')
const multer = require('multer')
const cors = require('cors')

const app = express()
const port = 3001
const storage = multer.memoryStorage()
const upload = multer({ storage: storage }).any();

app.use(cors());

app.post(ROUTE_YOU_WANT, upload, (req, res) => {
  fileContent = req.files[0].buffer.toString('utf8');
  res.header('Acess-Control-Allow-Origin', 'true');
  res.status(200).send()
})

app.listen(port, () => {
  console.log(`App listening on port ${port}`)
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment