I want to transfer data from a client to a server computer where both of them are using Node.js
. On client I'm using the libraries axios
and form-data
. On the server I'm using express
and multer
...
The client code that I'm using is the following:
const FormData = require('form-data');
const axios = require('axios');
let form = new FormData();
form.append("user", "someuser");
axios({
method: 'post',
url: 'http://localhost:9996/data',
data: form
})
.then(function (response) {
console.log(response.status);
})
.catch(function (response) {
console.log(response.status);
});
And the server code is the following:
const express = require('express')
const bodyParser = require('body-parser');
const multer = require('multer')
const app = express();
const upload = multer();
app.use(bodyParser.urlencoded({extended: true}));
app.post('/data', upload.none(), function (req, res, next) {
console.log(req.body);
res.sendStatus(200)
})
const port = 9996;
app.listen(port, () => {
console.log(`running on port ${port}`)
})
.on('error', function(err) {
console.log('stopped')
})
This code is functional and I manage to get the form
JSON
that I have created on the client as a request message on the server. However, the output of my req.body
on the server is as the following:
{ '----------------------------926328179431047129531240\r\nContent-Disposition: form-data; name':
'"user"\r\n\r\nsomeuser\r\n----------------------------926328179431047129531240--\r\n' }
This output is not formatted as a JSON object as I expected. Isn't the parameter upload.none()
from multer
supposed to parse req.body
as a JSON? Does anyone know what I'm getting wrong here and if there's any other parameter that I need to change in order to make the output on req.body to be formatted as a JSON object?
Observation: I know that if I create this JSON manually with const form = {"user":"someuser"}
I will have the output as an object on req.body
on the server. However, I'm using form-data
because on my original code I plan to read a huge file with createReadStream
on the client and write it with createWriteStream
on the server, and the library form-data
is the solution that I found to make axios
support streaming of data.
The reason for what you see is that multer
only parses the request when content-type
header is set to multipart/form-data
. You are not setting request headers so the request is send using application/x-www-form-urlencoded
, multer
ignores it and body-parser
do the parsing instead.
To fix it set headers on your request like this:
const FormData = require("form-data");
const axios = require("axios");
let form = new FormData();
form.append("user", "someuser");
// form.append("my_buffer", Buffer.alloc(10)); // or actual image
axios({
method: "post",
url: "http://localhost:8080/data",
data: form,
headers: form.getHeaders()
})
.then(function(response) {
console.log(response.status);
})
.catch(function(response) {
console.log(response.status);
});