Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Upload a file in React and send it to an Express server

I need to upload a file in React and then send it to an Express server (I'm new to Express so it's hard for me),

I succeed to upload the file in my React Component, but now I don't know how to send it to my back-end server made with Express.

What do I need to use ? Axios or Fetch ? Get or Post ? Thank you !

my App.js file (front-end)

    uploadFile = () => {
    const { currentFileName, currentFileType } = this.state;
    if (currentFileName && currentFileType) {
      fetch('http://localhost:5000/upload/files', {
        method: "POST",
        headers: {
          'Content-type': 'application/json'
        },
        body: JSON.stringify(this.state)
      })
      .then((res) => res.json())
      .then(res => {
        this.setState({
          errorMessage: "",
          successMessage: `Votre fichier ${currentFileName} a bien été uploadé !`
        });
        console.log(res);
        console.log(res.data);
      })
    } else {
      this.setState({
        errorMessage: "Veuillez choisir un fichier avant d'appuyer sur le bouton Upload !"
      });
    }
  }

and my server.js file (back-end)

const express = require('express');

const app = express();

const router = express.Router();

app.use(function(req, res, next) {
    res.header('Access-Control-Allow-Origin', 'http://localhost:3000');
    res.header('Access-Control-Allow-Credentials', true);
    res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
res.header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, DELETE');
next();
});

const bodyParser = require('body-parser');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));

app.post('/upload/files', (req, res) => {
    var fileName = req.body.currentFileName;
    var fileType = req.body.currentFileType;
console.log('Nom du fichier: ' + fileName + ' ' + 'Type du fichier: ' + fileType);
res.send(fileName + fileType);
});

const port = 5000;

app.listen(port, () => `Server running on port ${port}`);

I expect to get the state datas in localhost:5000/upload/files but when I go on the URL I have the message "Cannot GET /upload/files"

Can someone help me please ? Thank you !

like image 676
VersifiXion Avatar asked Dec 24 '18 13:12

VersifiXion


People also ask

How do I send files to a server in react?

Send a request to the server: After storing the selected file (in the state), we are now required to send it to a server. For this purpose, we can use fetch or Axios. (In this code, we use Axios a promise-based HTTP client for the browser and NodeJS). The file is sent to the service wrapped in a FormData object.

How do I upload files to express?

Open the local page http://127.0.0.1:2000/ to upload the images. Select an image to upload and click on "Upload Image" button. Here, you see that file is uploaded successfully. You can see the uploaded file in the "Uploads" folder.

How do you upload a file and send it to backend in react?

In order to upload files, the 'content-type' header must be set to 'multipart/form-data'. new FormData() creates a new empty formData object that we send as the payload in our POST request. Our POST request assumes there is an API endpoint on our backend server at http://localhost:3000/uploadFile. We're done!


2 Answers

You can use axios to upload the file.

const yourFile = file // Assume this is your file.

Now you need to add it to a form data.

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

now:

axios.post('/yourEndpoint', formData).then(res => {
  //Now do what you want with the response;
})

In your NodeJS app:

app.post('/yourEndpoint', function(req,res){
  fs.readFile(req.files.file.path, function(err, data){
    // Do something with the data (which holds the file information)
  });
});
like image 148
Harish Soni Avatar answered Sep 20 '22 19:09

Harish Soni


In your frontend grab your file

 <input type="file" id="inputGroupFile01" 
    onChange={(e) => this.onSelectImageHandler(e.target.files)}
/>

You must send the file to the server as a FormData as follows:

onSelectImageHandler = (files) => {
    const file = files[0];
    const formData = new FormData();
    formData.append('file', file)

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

Once you have your FormData setup, you can make the call with axios.

Then you need to install multer package on your server side $npm i -S multer, then on your server.js file.

const multer = require('multer');

You can configure multer just at the beginning after all requires.

const upload = multer({dest: 'public/uploads/'}).single('file');

Then in your route:

app.post('/upload/files', (req, res) => {
    upload(req,res, (err) => {
        const file = req.file
    const prevUrl = req.body.prevUrl.slice(21) //I use slice to cut the public part of the path, since mine is accessible from anywhere.
    if(!err){
        //here you could add some call to save the prevUrl "url of the file to called it later on your front"
        return User.findOneAndUpdate({_id:req.decoded.userId},{avatarUrl:avatarUrl}, (err, user) => {
            if(!err){       
                return console.log(err)
                })
                return res.json({success:true, message:"File has been successfully uploaded",avatarUrl:"http://localhost:3231/uploads/"+file.filename});
            }
            console.log(err);
        })
    }
    console.log(err);
    })
});

Hope it helps.

like image 26
vitomadio Avatar answered Sep 21 '22 19:09

vitomadio