fetch(REST+'/signup', {
mode: 'cors',
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({ id: id, pw: pw })
}).then(async (res) => {
let json = await res.json();
if (json.result === true) {
this.setState({ view: 'login' });
}
});
this is my client's POST request part.
my react app uses port 3000
and my REST server is using 80
I already declared using cors in my REST server like this
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(cors()); // enable CORS to prevent same origin policy error
and this is rest of my REST server code
app.post('/signup', (req, res) => {
console.log(req.body);
...
res.send(JSON.stringify({
result: true
}));
});
when I used cURL to test REST server, it says
$ curl --header "Content-Type: application/json" --request POST --data '{"id": "gksrlf2ek", "pw": "hangil2da!"}' http://localhost/signup
{"result":true}
but using my react app, REST server gets {}. empty object.
Related
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"
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
})
I have a node.js app connected to a dialogflow bot I created, in which there's only one file: app.js.
I have index.html, index.js UI for the bot, which when I open unconnected to app.js, runs perfectly. I get json response from app.js
However, when I tried to include the UI (index.html and index.js) in app.js, the post method is returning index.html instead of the json it returned before, resulting in error: "SyntaxError: Unexpected token < in JSON at position 0" (because index.html is returned instead of json)
Here's my app.js
const dialogflow = require('#google-cloud/dialogflow');
const uuid = require('uuid');
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
const port = 9000;
const sessionId = uuid.v4();
app.use(bodyParser.urlencoded({
extended: false
}));
// ------------------The following code is the one I use for including the UI----------------------------------
const path = require('path');
app.use(express.static('botui'));
app.use('/', function(req,res){
res.sendFile(path.join(__dirname+'/botui/index.html'));
});
// ------------------------------Code for including the UI ended-----------------------------------------------
// ------------------When I did not use the above code and just opened file://index.html it worked great-------
app.use(function (req, res, next) {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
res.setHeader('Access-Control-Allow-Credentials', true);
// Pass to next layer of middleware
next();
});
app.post('/send-msg',(req,res)=>{
runSample(req.body.MSG).then(data=>{
res.send({
statusCode: 200,
body: {},
headers: {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*'
},
Reply:data})
})
})
/**
* Send a query to the dialogflow agent, and return the query result.
* #param {string} projectId The project to be used
*/
async function runSample(msg, projectId = 'bot_ID') {
// Create a new session
const sessionClient = new dialogflow.SessionsClient({
keyFilename:"BOT-KEY.json"
});
const sessionPath = sessionClient.projectAgentSessionPath(projectId, sessionId);
// The text query request.
const request = {
session: sessionPath,
queryInput: {
text: {
// The query to send to the dialogflow agent
text: msg,
// The language used by the client (en-US)
languageCode: 'en-US',
},
},
};
// Send request and log result
const responses = await sessionClient.detectIntent(request);
console.log('Detected intent');
const result = responses[0].queryResult;
console.log(` Query: ${result.queryText}`);
console.log(` Response: ${result.fulfillmentText}`);
if (result.intent) {
console.log(` Intent: ${result.intent.displayName}`);
} else {
console.log(` No intent matched.`);
}
return result.fulfillmentText;
}
app.listen(port,()=>{
console.log("Running on port: " + port)
})
And here's the code from index.js which sends the POST request:
fetch(url, {
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*'
},
method: 'POST',
body:data
})
.then(res => res.json())
.then(response => {
console.log(response);
serverMessage(response.Reply);
})
.catch(error => console.error('Error h:', error));
It seems you should replace app.use('/', function(req,res){ to app.get('/', function(req,res){
take a look at Difference between app.use and app.get in express.js
I've set up an API with a create user and an auth route. The auth route should set an httpOnly cookie containing a JWT, and should send JSON for the client to store in localhost.
In the front-end I'm doing a simple fetch.
The server responds 200 and with the JSON I expect, but somehow, the cookie doesn't get set.
However, in Postman, the cookie does indeed get set.
Express server
const express = require('express')
const cors = require('cors')
// boilerplate stuff
app.use(express.json())
app.use(cors({ origin: 'http://localhost:3000', credentials: true }))
app.post('auth', (req, res) => {
// fetch user from db, validation, bla bla bla
const token = jwt.sign({ issuer: user.id }, keys.private, { algorithm: 'RS256' })
res.cookie('token', token, { httpOnly: true })
res.json(user)
})
Next.js front-end
const handleSubmit = async (e) => {
e.preventDefault()
try {
const res = await fetch('http://localhost:5000/api/v1/auth', {
method: 'post',
mode: 'cors',
credentials: 'include',
headers: {
'content-type': 'application/json',
'accept': 'application/json',
},
body: JSON.stringify(formState),
})
const data = await res.json()
console.log(data)
} catch (err) {
console.error(err)
setError(err.message)
}
}
'Twas resolved.
I was looking in Session Storage as opposed to Cookies in my devtools.
I'm trying to send data from client's inputs based on React.js to server written in Node.js which put it to DB. I have no errors and after submit, new records show in database but they are empty. I have two inputs and I'm joining them in one string and trying send it to DB (so DB has one property). Can you check my code and see what is wrong? Maybe something with headers...
This is function in React component:
addCompetitor = event => {
event.preventDefault();
const name = this.state.draftCompetitorName;
const lastname = this.state.draftCompetitorLastname;
fetch(`http://localhost:5000/competitors`, {
method: "POST",
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({ name: `${name}${lastname}` })
})
.then(response => response.json())
};
This is server POST response:
app.post("/competitors/", urlencodedParser, function (req, res) {
const newCompetitor = new Competitor({ name: req.body.name });
newCompetitor.save().then(competitor => res.json(competitor));
});
And it's app configuration:
app.use(function (req, res, next) {
res.setHeader("Access-Control-Allow-Origin", "http://localhost:3000");
res.setHeader(
"Access-Control-Allow-Methods",
"GET, POST, OPTIONS, PUT, PATCH, DELETE"
);
res.setHeader(
"Access-Control-Allow-Headers",
"Content-Type",
"X-Requested-With"
);
res.setHeader("Access-Control-Allow-Credentials", true);
next();
});
If not first install bodyparser. This parses incoming request bodies in a middleware before your handlers, which will be available under the req.body property.
app.use(bodyParser.json({
limit: '50mb',
parameterLimit: 100000
}))
Alternatively what is the express version you are using ? Is it greater than 4.16? Then you can also use
app.use(express.json());
See notes here
https://expressjs.com/en/api.html#express.json
Modify your code
let databody = {
"name": `${name}${lastname}`,
"otherprop": this.state.otherprop
}
From frontend use
body: JSON.stringify(databody),
In express end remove urlencodedParser , should be like below:
app.post("/competitors", function (req, res) {
console.log(req.body);
});
You are using urlencodedParser as a middleware so I guess you used bodyParser.urlencoded({}) but your request is sending a json format. Try adjusting your request by adding the following header:
'Content-Type': 'application/x-www-form-urlencoded'
EDIT:
Also body should be in the following format:
body: `name=${name}${lastname}`