How to read formdata in nodejs - node.js

I'm using ionic angular in frontend and I' trying to send a formdata that contains a file and also 2 strings. Apparently its being sent however I don't know how to read that information on the server side
FRONTEND
private fil3: File;
changePicture(fileChangeEvent){//this functions is called by an input file
this.fil3 = fileChangeEvent.target.files[0];
let a1 = "a1"
let a2 = "a2"
let b1 = "b1"
let b2 = "b2"
let formData = new FormData();
formData.append('photo', this.fil3, this.fil3.name);
formData.append(a1, a2);
formData.append(b1, b2);
fetch('http://localhost:3000/up', {
method: 'POST',
body: formData,
headers:{
/* 'Content-Type': 'application/json' */
'Content-Type': "multipart/form-data"
},
mode: "cors",
}).then(res =>{ res.json().then((data)=>{
console.log("filename: "+data.filename);
console.log("originalname: "+data.originalname);
console.log("message: "+data.message);
this.avatar="../../assets/uploads/"+data.filename
})
})
.catch(error => {console.error('Error:', error)})
.then(response => {console.log(response)});
}//changePicture
SERVER
function updatePicture (req, res) {
console.log("req.body: "+req.body)
}
On the server side I'm just trying to read each element of the formdata individually so I can work with them. These elements are the file and two other strings(a1,a2,b1,b2). This console.log on the server prints this req.body: [object Object]
I tried things like
console.log("req.body: "+req.body.a1)
console.log("req.body: "+req.body.[1])
but certainly do not work, I get undefined, I have no idea how to handle this, any word of advice?
MINIMUN REPRODUCIBLE CODE OF BACKEND
const express = require ('express')
const bodyParser = require ('body-parser')
const app = express()
const api = express.Router()
const cors = require('cors')
app.use(bodyParser.urlencoded({ extended:false}))
app.use(bodyParser.json())
app.use(cors({
origin: true
}));
const PORT = 3000;
app.listen(config.port, ()=>{
console.log(`Server running on port: ${PORT}`)
})
api.post('/up', (req, res) =>{
console.log(req.body)
})

Firstly, remove this part :
headers:{
/* 'Content-Type': 'application/json' */
'Content-Type': "multipart/form-data"
}
because if you define Content-Type manually, you can't inform about boundary information. It need to managed automatically by browser because you send files too.
Secondly, you need a library to parse you're multi-part data. You can use formidable :
const formidable = require('formidable');
//You're other codes
app.post('/up', (req, res) => {
const form = formidable({ multiples: true });
form.parse(req, (err, fields, files) => {
console.log('fields: ', fields);
console.log('files: ', files);
res.send({ success: true });
});
});
For my side this log something like :
fields: { a1: 'a2', b1: 'b2' }
files: {
file: PersistentFile {
...

Related

Unirest post request body

I want to be able to send data from one server to another, started on the same device (to start with). I have this:
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
const urlEncodedParser = bodyParser.urlencoded({extended: false});
app.post('/test', urlEncodedParser, (request, response) =>
{
console.log(request.body);
});
app.listen(9999);
console.log('Server started on port 9999');
const unirest = require('unirest');
unirest.post('http://127.0.0.1:9999/test').headers({'Accept': 'application/json', 'Content-Type': 'application/json'}).send({"test1": 123321, "test2": "321123"})
.then((response) =>
{
console.log(response.body);
});
It looks logical, but console.log(request.body); gives empty object {} yet in the post requests I do send some data using .send. How to get access to that data in the request?
You are sending data with Content-Type: 'application/json', so on the server you need to connect middleware not for urlencoded, but for json. In addition, you do not need to separately connect the body-parser since it is included in express and you can connect the necessary middleware like this:
Server:
const express = require('express');
const app = express();
app.post('/test', express.json(), (request, response) => {
console.log(request.body);
response.end('OK');
});
app.listen(9999, () => console.log('Server started on port 9999'));
Client:
const unirest = require('unirest');
unirest
.post('http://127.0.0.1:9999/test')
.headers({ Accept: 'application/json', 'Content-Type': 'application/json' })
.send({ test1: 123321, test2: '321123' })
.then((response) => {
console.log(response.body);
});

Why can't i see the data in browser (node-fetch)

I am trying to display this to front-end(html) part but i am not able to see it in browser console.I have tried without the "app.get" part. It does work when i run nodejs but it doesnt display it in browser. url and api-key is removed from here for safety reasons.
const express = require('express');
const app = express();
const fetch = require('node-fetch');
let url ='url';
let apiKey = 'api-key';
app.get('/', req, res =>{
res.sendFile(path.join(__dirname,'index.html'));
fetch(url,{
method: 'GET',
headers:{
'Accept': 'application/json',
'Content-Type': 'application/json',
'Authorization': 'Basic ' + apiKey,
'Access-Control-Allow-Origin':'*'
},
credentials: 'same-origin'
})
.then(res =>res.json())
.then(data => console.log(data))
.catch(err => {
console.log(err);
})
})
app.listen(3000, () => {
console.log('Example app listening on port 3000!')
});
I fixed it. the path was messed up because i didn't have "const path = require('path');" and i fixed it. But also req wasn't defined so i had to put it inside a function app.get('/', function(req, res). Thank you for the help

Express JS is receiving an empty req.body from ReactJS

I am currently having a problem with React and Express JS form submit function. It seems like my nodeJS running on port 5000 is receiving an empty object from my ReactJS running on port 8080 using fetch method.
React : Contact.js
handleSubmit(e)
{
e.preventDefault();
var data = {
name: this.state.name,
contact: this.state.contact,
email: this.state.email,
message: this.state.message,
}
var url = 'http://localhost:5000/api/insertUsers';
fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
mode: 'no-cors',
body: JSON.stringify(data),
})
.catch((error) => {
console.log(error);
});
}
NodeJS : server.js
const express = require('express');
const { Client } = require('pg');
const bodyParser = require('body-parser');
const app = express();
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.post('/api/insertUsers', function(req, res) {
res.setHeader('Content-Type', 'text/plain')
res.write('you posted:\n')
res.end(JSON.stringify(req.body, null, 2))
});
app.listen(5000, () => {
console.log('listening on port 5000');
});
Change the order of bodyparser middleware like this.
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
You are sending a request with the content-type of 'application/json' but express is expecting a content-type of 'text/json'. Usually, when req.body is empty content-type is the first suspect you should be looking at.
I am ashamed that I struggled with this for hours. I still haven't gotten it to work with file uploads.
But I did get it to work with a normal form by encoding JSON and sending that along with axios, instead of fetch
My js code
var data = {
id: this.state.id,
}
console.log('data',data)
var bodyFormData = new FormData();
bodyFormData.set('id', this.state.id);
var url = ' http://localhost:3000/get-image-by-id';
console.log("bodyFormData: ", bodyFormData);
axios({
method: 'post',
url: url,
data: data,
// headers: {'Content-Type': 'multipart/form-data' }
headers: {'Content-Type': 'application/x-www-form-urlencoded' }
})
.then(function (response) {
//handle success
console.log(response);
})
.catch(function (response) {
//handle error
console.log(response);
});
Form Code
<form method="POST" onSubmit={this.handleSubmit} >
<label>
Transaction ID
<input
type="text"
name="id"
value={this.state.id}
onChange={this.handleInputChange}
/>
</label>
<button type="submit">Submit</button>
</form>
```
EDIT
fetch(url, {
method: 'POST',
body: JSON.stringify(data),
mode: 'no-cors'
}).then((result)=>{
console.log("output" + result.json());
})
.catch((error) => {
console.log(error);
});
EDIT 2
for backend, install cors and add the following lines before route.
var cors = require('cors')
app.use(cors())
EDIT 3
perform npm install morgan then copy these lines inside the code
var morgan = require('morgan');
app.use(morgan('dev'));
I didn't look at your code close enough. My bad
app.post('/api/insertUsers', function(req, res) {
res.setHeader('Content-Type', 'text/plain')
res.write('you posted:\n')
res.end(JSON.stringify(req.body, null, 2))
});
Should be
app.post('/api/insertUsers', function(req, res) {
res.json(req.body)
});
try using axios instead of fetch
I rewrote ur code like this and it works perfectly
server
const express = require('express');
const { Client } = require('pg');
const bodyParser = require('body-parser');
const app = express();
const cors = require("cors");
app.use(cors());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.post('/api/insertUsers', function(req, res) {
// console.log(req);
console.log(req.body);
res.send(req.body);
});
app.listen(3001, () => {
console.log('listening on port 3001');
});
react (ensure you have axios installed)
handleSubmit(e){
e.preventDefault();
var data = {
name: "zadiki",
contact: "0702002109",
email: "zadiki",
message: "test",
}
console.log("wow");
var url = ' http://localhost:3001/api/insertUsers';
axios.post(url,data)
.then(response=>console.log(response))
.catch(e=>console.log(e))
}
Hello I ended up getting mine working after I ran into the same problem.
I noticed your react code has "mode: 'no-cors'," that was causing problems with mine so I removed it.
-------- Below is my handle submit code for React ------------
const handleSubmit = (event) => {
event.preventDefault();
const url = "http://localhost:3001/register"
const options = {
method: "POST",
body: JSON.stringify(formData),
headers: {
"Content-Type": "application/json"
}
}
fetch(url, options)
.then(res => res.json())
.then(res => console.log(res))
}
I used express.json instead of bodyParser. You also had a typo in your express code, it should say res.send instead of res.end
--------- Below is my Node Express Code -----------
const express = require('express');
const app = express();
const cors = require('cors');
const multer = require('multer');
// Middlewares
app.use(cors({ origin: 'http://localhost:3000', }))
app.use(express.json())
app.use(express.urlencoded({ extended: true }))
app.use(multer().array());
app.post('/register',(req, res) => {
console.log(req.body)
res.status(200)
.json({status:"Success", data:{body: req.body })
});
app.listen(3001, () => console.log(`Running on 3001`))
I was able to send form data using postman and react using the code above. Feel free to change it to accommodate your needs.

NextJS and React: Cannot read property 'email' of undefined

I try to send data from my client to my server. For that, i use React with NextJS, because you have the server and client-side in one app.
I use the following handleSubmitFunction:
handleSubmit() {
const email = this.state.email;
fetch('/', {
method: 'POST',
body: email,
});
}
and this is my server.js file in the located in / at my project
const express = require('express')
const next = require('next')
const bodyParser = require('body-parser')
const dev = process.env.NODE_ENV !== 'production'
const app = next({ dev })
const handle = app.getRequestHandler()
app.prepare()
.then(() => {
const server = express()
//parse application
server.use(bodyParser.urlencoded({ extended: false}))
//parse application/json
server.use(bodyParser.json())
server.post('/', (req, res) => {
console.log(req.body.email);
res.end("success!");
})
server.get('*', (req, res) => {
return handle(req, res)
})
server.listen(3000, (err) => {
if (err) throw err
console.log('> Ready on http://localhost:3000')
})
})
.catch((ex) => {
console.error(ex.stack)
process.exit(1)
})
When the handleSubmit Function is running, i get the following Output from the Server Console:
Cannot read property 'email' of undefined
Where exactly is my mistake?
I have little experience in node JS environments. I would be very grateful if you could show me concrete solutions. Thank you for your replies.
It seems you have to parse header and JSON.stringify the email.
fetch('/', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({email:email}),
}).then((res)=> console.log('Worked'))

Receiving Multipart form data in node js

I am trying to send multipart form-data from postman to my nodejs restify server. But the request.files is coming undefined.
Below is my code and a screenshot from my postman.
//Code
var restify = require('restify');
var os = require('os');
var server = restify.createServer({
name: 'New App',
version: '1.0.0'
});
server
.use(restify.acceptParser(server.acceptable))
.use(restify.fullResponse())
.use(restify.bodyParser({mapParams: true,
mapFiles: true,
keepExtensions: true,
uploadDir: os.tmpdir()
}));
server.post({path: '/api/image', version: '1.0.0'},controllers.image.addImage);
exports.addImage = function (req, res, next) {
console.log("Files : "+req.files);
}
OutPut :
Files : undefined
screenshot :
https://i.stack.imgur.com/0hTX0.png
You can use restify-multipart-body-parser - see:
https://www.npmjs.com/package/restify-multipart-body-parser
Simply use : https://www.npmjs.com/package/multi-part-form-data-upload
It automatically parse files and another type of multipart data:
// Express
const uploader = require('multi-part-form-data-upload')(options /* config options */ );
const app = express();
app.post('/uploads',uploader, (req, res) => {
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ body: req.body }));
});
// OR Http
const http = require('http');
const uploader = require('multi-part-form-data-upload')(options /* config options */ );
const server = http.createServer(async (req, res) => {
if (req.url === '/uploads' && req.method.toLowerCase() === 'post') {
await uploader(req, res, () => {
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ body: req.body }));
});
return;
}
}

Resources