Send Formdata with Fetch API

Asked

Viewed 360 times

1

I’m trying to send a Formdata() to the backend via Fetch API, but I can’t read the form inputs in NODEJS. By the way, req.body is empty.

I’m wearing the body-parser and express.

Backend:

const express = require('express');
const app = express();
const bodyParser = require('body-parser');

app.use(express.static('./static/'));

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));

app.post('/teste', (req,res) => {
    console.log(req.body);
    res.send('teste');
});

app.get('/', (req,res) => {
    res.sendFile(__dirname + '/index.html');
});

app.listen(3000, () => {
    console.log('rodando...');
});

module.exports = () => app;

Frontend:

window.onload = () => {
    var form = document.getElementById('myForm');

    form.addEventListener('submit', (evt) => {
        evt.preventDefault();
        var myHeader = new Headers();
        // myHeader.append('Content-type', 'application/x-www-form-urlencoded');
        // myHeader.append('Content-type', 'multipart/form-data');
        
        var myFormData = new FormData(form);
        fetch('/teste', {
            method: 'POST',
            headers: myHeader,
            body: myFormData
        }).then((retorno) => {
            console.log(retorno);
        }).catch();
    });
}

I can read something in req.body only when Content-type is equal to 'application/x-www-form-urlencoded'. In this case this is what appears on the console.log():

{
  '------WebKitFormBoundaryUlQT9OMwOZvpVQ0U\r\nContent-Disposition: form-data; name': '"nome"\r\n' +
    '\r\n' +
    'digitando algo \r\n' +
    '------WebKitFormBoundaryUlQT9OMwOZvpVQ0U\r\n' +
    'Content-Disposition: form-data; name="idade"\r\n' +
    '\r\n' +
    'ABACATE\r\n' +
    '------WebKitFormBoundaryUlQT9OMwOZvpVQ0U--\r\n'
}

1 answer

2


You will need some middleware to process Multipart/formdata in the route of the nodejs. Multer is the most used option:

https://github.com/expressjs/multer

In the doc itself there are several examples...but I’ll add one here so you can have as reference:

<form action="/profile" method="post" enctype="multipart/form-data">
    <input type="file" name="avatar" />
</form>

On the route of the Node.js:

var express = require('express')
var multer  = require('multer')
var upload = multer({ dest: 'uploads/' })

var app = express()

app.post('/profile', upload.single('avatar'), function (req, res, next) {
  // req.file is the `avatar` file
  // req.body will hold the text fields, if there were any
})

app.post('/photos/upload', upload.array('photos', 12), function (req, res, next) {
  // req.files is array of `photos` files
  // req.body will contain the text fields, if there were any
})

var cpUpload = upload.fields([{ name: 'avatar', maxCount: 1 }, { name: 'gallery', maxCount: 8 }])
app.post('/cool-profile', cpUpload, function (req, res, next) {
  // req.files is an object (String -> Array) where fieldname is the key, and the value is array of files
  //
  // e.g.
  //  req.files['avatar'][0] -> File
  //  req.files['gallery'] -> Array
  //
  // req.body will contain the text fields, if there were any
})

Now a plus: i’ve used formdable to process file uploads. https://www.npmjs.com/package/formidable

var formidable = require('formidable')
[...]
var form = new formidable.IncomingForm();
form.parse(req, function (err, fields, files) {}
[...]

Solution

I did not test locally, but in your code I believe this can solve (the section is on line 4 and 11):

const express = require('express');
const app = express();
const bodyParser = require('body-parser');
const upload = multer()

app.use(express.static('./static/'));

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));

app.post('/teste', upload.none(), (req,res) => {
    console.log(req.body); // req.body contém text fields
    res.send('teste');
});

app.get('/', (req,res) => {
    res.sendFile(__dirname + '/index.html');
});

app.listen(3000, () => {
    console.log('rodando...');
});

module.exports = () => app;

Browser other questions tagged

You are not signed in. Login or sign up in order to post.