简体   繁体   中英

Passing file from React app to Node app to upload to S3, file is undefined when defining the upload params?

I'm trying to make my own personal resume using React and Node, and I've been having issues with the upload to AWS S3 for a few hours now.

I fire an event when submitting the form with the file :

onSubmitChange = () => {
    const data = new FormData()
    data.append('url', this.state.url);
    data.append('name', this.state.name);
    data.append('description', this.state.description);
    data.append('filePath', this.state.file);

    fetch('http://localhost:3001/new-experience', {
        method: 'post',
        headers: {'Content-Type': 'multipart/form-data'},
        body: data
        // body: JSON.stringify({
        //     url: this.state.url,
        //     name: this.state.name,
        //     description: this.state.description,
        //     filePath: this.state.file,
        // })
    })
    .then(resp => console.log(resp));
}

Which then triggers this

AWS.config.update({
    accessKeyId: process.env.AWSAccessKeyId,
    secretAccessKey: process.env.AWSSecretKey,
    region: 'eu-west-3'
});

const s3 = new AWS.S3();
app.post('/new-experience', (req, res) => {
    const { url, name, description, filePath } = req.body;

    console.log(filePath);

    const params = {
        Bucket: 'bucket-xxxx',
        Body : fs.createReadStream(filePath),
        Key : "folder/test.png"
     };

    s3.upload(params, function (err, data) {
        //handle error
        if (err) {
          console.log("Error", err);
         }

        //success
        if (data) {
          console.log("Uploaded in:", data.Location);
        }
    });

    db('mael-landrin').insert({
        experienceurl: url,
        experiencename: name,
        experiencedescription: description
    })
    .into('experiences')
    .then(resp => res.status(200).send('Experience added'))
    .catch(err => res.status(400).send(err));
})

The console log in the 3rd line of the "/new-experience" route returns undefined, which I believe is why fs.createReadSream(filePath) gives undefined to the function, which is why I get the error.

The last console.log() in the React part gives me everything right, 3 strings and a file ( a .png file ).

Apple Website for Apple. https://www.apple.com/ File {name: "Entˆte Mozzarelline 25g x 8.jpg", lastModified: 1583766837712, lastModifiedDate: Mon Mar 09 2020 16:13:57 GMT+0100 (Central European Standard Time), webkitRelativePath: "", size: 454282, …}

Anyone knows where it could come from ?

The file object will not be present on your req.body. You need to install a third party module for file upload(of course there are "raw" ways to do it, but i don't know how and see no reason to do so):

npm i express-fileupload

In your express root file:

const fileUpload = require('express-fileupload');
app.use(fileUpload());

Then in your file upload route:

const { url, name, description} = req.body;
const fileObject = req.files.filePath;//"filePath" is misleading, but this is the name you chose.  
const fileData = fileObject.data;

const params = {
        Bucket: 'bucket-xxxx',
        Body : fileData,
        Key : "folder/test.png"
     }

What you probably intended to do is to append file to data not file path. So do this

data.append('file', this.state.file);

You also need a middleware to parse multipart form data.

Multer works really well.

https://www.npmjs.com/package/multer

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM