I made a node server with the three packages express, body-parser and cors.
I am trying to access data from client-side in my app.js with an async/await function that has a post request with the required data that I want to fetch
here's the fetch request and the post request in app.js, I am trying to pass the data [temperature, date, userResponse] via the postData function in app.js:
//post routes
const postData=async function postData(url = 'http://api.openweathermap.org/data/2.5/weather?zip=', data = {}) {
const response = await fetch(url, {
method: 'POST',
mode: 'cors',
cache: 'no-cache',
credentials: 'same-origin',
headers: {
'Content-Type': 'application/json'
},
redirect: 'follow',
referrerPolicy: 'no-referrer',
body: JSON.stringify(data)
});
return await response.json();
}
postData('/add', {temperature: '1', date: '2', userResponse: '2'});
}
and here's the server side code where I made an add route as post route:
// Setup empty JS object to act as endpoint for all routes
projectData = {};
// Require Express to run server and routes
const express = require('express');
// Start up an instance of app
const app = express();
/* Middleware*/
//Here we are configuring express to use body-parser as middle-ware.
const bodyParser = require('body-parser')
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
// Cors for cross origin allowance
const cors = require('cors');
app.use(cors());
// Initialize the main project folder
app.use(express.static('website'));
const port = 3000;
// Setup Server
const server=app.listen(port, ()=>{console.log(`running on localhost: ${port}`)});
app.get('/all', sendData);
function sendData (request, response) {
response.send(projectData);
};
// TODO-ROUTES!
const data=[]
app.post('/add', function(req,res){
data.push(req.body)
console.log(data)
})
here's what I got when I ran the project on localhost:3000
I want the the parameters temperature, date and userResponse to appear in the console
the errors at line 35 related to the post request are :
app.js:35 POST http://localhost:3000/add net::ERR_EMPTY_RESPONSE
app.js:48 Uncaught (in promise) TypeError: Failed to fetch
never mind the errors at the two above lines related to the get request
in vs code I can see this(the temperature, date and userResponse appear in the terminal but don't appear in the localhost:3000 console in the browser):
I just need the client-side to pass data to server-side dynamically and not just pass the response in the server-side
You are not sending any response back from the server. Send some response as below
app.post('/add', function(req,res){
data.push(req.body)
console.log(data)
return res.send({}); //return whatever response you need to send
})
Related
I need to receive a JSON from my front in React. But the JSON comes to me in a strange way (an object with the data in string), I don't know how to return it to type object again.
I send this.
const data = {
email: 'emailc#email.com',
password: 'test'
}
const options = {
method: 'POST',
body: JSON.stringify(data),
mode: 'no-cors',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
}
const onsubmit = (e) => {
//evitamos que se haga la peticion en automatico
e.preventDefault();
fetch('http://localhost:3001/user/signin',options)
.then(res => res.json())
.catch(error => console.error('Error:', error))
.then(response => console.log('Success:', response));
console.log('send on submit');
}
and I get this on the express server:
[Object: null prototype] {
'{"email":"emailc#email.com","password":"test"}': ''
}
My server is configured in this way:
const express = require('express');
const app = express();
const morgan = require('morgan');
const cors = require('cors');
const {mongoose} = require('./src/database/connection')
const Parser = require("body-parser").urlencoded({ extended: false });
//config
app.set('port', process.env.PORT || 3001);
//middlewares
app.use(morgan('dev'));
app.use(Parser);
app.use(cors()); //accepts connection from all directions
//Routes
app.use(require('./src/test'));
app.use(require('./src/routes/users'));
//Server
app.listen(app.get('port'), (req, res) => {
console.log(`Server on port ${app.get('port')}`);
})
I think I have misconfigured the body-parser, please help, it is my first API.
'Content-Type': 'application/x-www-form-urlencoded'
If you tell the server you are sending Form Encoded data then it is going to try to parse what you send as Form Encoded data.
Don't lie.
If you are sending JSON, say so:
'Content-Type': 'application/json'
const Parser = require("body-parser").urlencoded({ extended: false });
You also need a body parser that supports JSON.
const Parser = require("body-parser").json();
But Express has a built-in body parser and variable names starting with capital letters are traditionally reserved for constructor functions / classes.
const parser = express.json();
Aside:
mode: 'no-cors'
If you are making a cross-origin request then that will break it.
If you are making a same-origin request then that will do nothing.
Remove it.
This question already has an answer here:
Error when accessing API with fetch while setting mode to 'no-cors' [duplicate]
(1 answer)
Closed 1 year ago.
I'm using fetch web API to send a post method request from reactJS to express NodeJS server both on localhost with different ports.
Client Fetch API
fetch("http://localhost:8081/test",
{
method: "post",
mode:"no-cors",
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
username : "John Doe",
password : "It's a secret"
})
}).then(function(response)
{
if(response.ok)
{
return response.json();
}else
{
console.log(response)
}
}).then(function(body) { console.log(body); }).catch((error) => { console.log(error) });
Server - Express NodeJS
var express = require('express');
var bodyParser = require('body-parser');
var cors = require('cors');
var app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(cors())
app.post('/test', function (req, res)
{
return res.send({ message: 'Any response' });
})
I receive my POST data from client with no issue, But i get no response from server. Almost tried everything but i get this error on response
body: (...)
bodyUsed: false
headers: Headers {}
ok: false
redirected: false
status: 0
statusText: ""
type: "opaque"
url: ""
Any help appreciated.
Thanks to #mehowthe, This issue was fixed by removing mode:"no-cors"
MRE -> node-server : react app
When I send a POST request using Postman, I get the expected result. This is the request that I am sending using Postman
and test sent gets printed to the console of my node server
If I send a request from my react form however, test sent does not print to the console, but the catch block of my fetch request get's executed and err is printed to the console of my react app, followed by {}.
I would like to know why my POST request is not working and is not getting received by the server
Below is the function that I call when someone clicks the submission button of my form created in react
Function called on form submission
nodeUrl = 'https://localhost:6060?'
const submitData = async () => {
fetch(nodeUrl, {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({'test': 'test'})
}).then((res) => {
alert('then')
}).catch((err) => {
alert('err')
alert(JSON.stringify(err))
})
}
}
This is the server that I run using node server.js
server.js
server.post('/', function(req, res) {
console.log('test sent')
mailer.messages().send(req.body)
.then((mes) => {
console.log(mes)
res.json({ message: 'Thanks for your message. Our service team has been notified and will get back to you shortly.' })
}).catch(err => {
console.log(err)
res.json(err);
})
});
The majour issue here is due to CORS. CORS support can be used to overcome this. Just keep in mind to have this only for development mode(see below codes).
But, as per the Postman's snapshot and provided GitHub repositories, the request from Front-end should be of multipart/form-data type. Thus, the Front-end code would look like this
const nodeUrl = "http://localhost:6060/";
const submitData = async () => {
// create a FormData object
const formData = new FormData();
formData.append('form', 'example#email.com');
formData.append('to', 'example#email.com');
// this auto adds 'multipart/form-data' + HASH header in the request
fetch(nodeUrl, {
method: "POST",
body: formData
})
.then(res => {
console.log(res);
}).catch(err => {
console.log('Error -', err);
});
};
To handle multipart/form-data request in the ExpressJS, you need a plugin Multer.
const express = require('express');
const bodyParser = require('body-parser');
const multer = require('multer'); // for 'multipart' type request
const server = express();
const upload = multer();
// allow CORS requests in development mode
if (process.env.NODE_ENV === 'development') {
// Server run command - "NODE_ENV=development node server.js"
const cors = require('cors');
server.use(cors());
}
server.use(bodyParser.json());
server.use(bodyParser.urlencoded({extended: true}));
// using Multer middleware form extracting 'FormData' payload
server.post('/', upload.none(), function(req, res) {
console.log('Received body', req.body);
... // other codes
});
Strategy 2(plain JSON) -
If that 'multipart/form-data' strategy was unintentional and you just want to send simple JSON, use below codes -
In Front-end, trigger API request as -
fetch(nodeUrl, {
method: "POST",
headers: {
'Content-Type': 'application/json', // this needs to be defined
},
body: JSON.stringify({ from: 'some#email.com', to: 'other#email.com' })
})
In server, just ignore codes related to Multer and only keep your API as -
server.post('/', function(req, res) {
console.log('Received body', req.body);
... // other codes
});
I ended up using a better fetch request, which was put together for me by selecting code -> Javascript Fetch in Postman(under the save button)
var myHeaders = new Headers();
myHeaders.append("Content-Type", "application/x-www-form-urlencoded");
var urlencoded = new URLSearchParams();
urlencoded.append("from", "example#email.com");
urlencoded.append("test", "test");
var requestOptions = {
method: 'POST',
headers: myHeaders,
body: urlencoded,
redirect: 'follow'
};
fetch("http:localhost:6060/, requestOptions)
.then(response => {
if (response.ok){
response.json().then(json => {
console.log(json)
})
}
})
.catch(error => console.log('error: ', error))
my api is not taking data from client sided code to the /api enpoint I have created on the localhost of the webserver on port 3000. How do I get it to take the server sided code to take the post request and console.log(request); correctly if it Page started
(index):23 POST https://goldengates.club:3000/api net::ERR_CONNECTION_TIMED_OUT
(anonymous) # (index):23
goldengates.club/:1 Uncaught (in promise) TypeError: Failed to fetch
Client Sided Code:
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<script>
console.log("Page started");
const num1=1;
const num2=2;
const data=35;//{num1,num2};
const options =
{
method: 'POST',
headers:
{
"Content-Type": "application/json"
},
body: JSON.stringify(data)
};
fetch('https://goldengates.club:3000/api'/*'https://goldengates.club/Cypher-Network/fetchTest.js'*/,options);
</script>
</body>
</html>
server sided code:
const express = require('express');
const app = express();
app.listen(3000,()=>console.log('listening on port 3000'));
app.use(express.static('public'));
app.post('/api',(request,response)=>
{
response.setHeader("Content-Type", "application/json");response.send({ statusCode:200, customMessage : 'Sucess', status : true })
console.log(request);
response.end();
});
the function fetch returns a promise, in order to use it, you need to call the then method, like so:
// backend code
app.post('/example', (req, res) => res.json({ data: 'abc' }));
// frontend code
fetch('/example', { method: 'post' }).then(r => r.json()).then(d => alert(d.data));
I think the way you show in your code, it will just store the function of how to compute the result of promise, not execute it and produce actual result (data fetched and passed to alert). With the Promise.then method, you can pass data the way you were doing, with Content-Type: application/json header and body: JSON.stringify(object).
I am trying to send data through axios request to my backend script, but the body looks empty.
Here's a request sent from front-end:
axios.request({
method: 'GET',
url: `http://localhost:4444/next/api`,
headers: {
'Authorization': token
},
data: {
next_swastik: 'lets add something here'
},
}).then((res)=>{
console.log("api call sucessfull",res);
}).catch((err)=>{
console.log("api call unsucessfull",err);
this.props.toggleLoading(false);
})
Here's a back-end:
app.get('/next/api', verifyToken, function(req, res) {
console.log(req.body);
})
But I am getting {} empty body. I am getting headers and other data but not data.
GET requests should not have a body.
Change the method from 'GET' to 'POST'
Like so:
axios.request({
method: 'POST',
url: `http://localhost:4444/next/api`,
headers: {
'Authorization': token
},
data: {
next_swastik: 'lets add something here'
},
})
and change your api to expect a post
app.post('/next/api', verifyToken, function(req, res) {
console.log(req.body);
});
or
Change the data property to params
axios.request({
method: 'GET',
url: `http://localhost:4444/next/api`,
headers: {
'Authorization': token
},
params: {
next_swastik: 'lets add something here'
},
})
and change the api to log out the params
app.get('/next/api', verifyToken, function(req, res) {
console.log(req.params);
});
and like #MaieonBrix said, make sure that your headers contain the content type that you are sending.
It looks like you only have two points left to make it work :
one : the http method should be set to POST instead of GET since you want to send something.
two : you can then add the http header (like what you did with the authorization header) Content-Type: 'application/json`
On the back-end don't forget to use some kind of body parser utility package like this one : body-parser and set it up with your app.
I suppose your server is using express, here is how you will do it with express :
const express = require('express');
const app = express();
const bodyParser = require('body-parser')
const jsonParser = bodyParser.json();
app.use(jsonParser); // use it globally
app.get('your_route', jsonParser, otherMiddleware, (req, res) => ...); // use it for specific routes
/* ... rest of your code */
If you get an error that "bodyParser is deprecated", try this -
app.use(express.json()); //To parse JSON bodies (Applicable for Express 4.16+)
And use "post" method, if you want to get data from body of the HTTP request.
Try this
this.axios('realties', { params: this.filter })