Im sending a request to my local server in my react app like this
fetch("http://localhost:4000/signup", {
method: "POST",
mode: "no-cors",
body: JSON.stringify({ name: "Joe", lname: "Doe" }),
headers: {
"Content-Type": "application/json",
},
})
And the problem is that im getting empty object on the req.body on my local server.
app.post('/signup', (req, res) => {
console.log(req.body);
console.log('post request sent');
})
How could i fix it that i could see the content which is being sent from the fetch body?
You appear to have two problems here each of which, by themselves, would cause the symptoms you describe.
First, as per the documentation for req.body:
Contains key-value pairs of data submitted in the request body. By default, it is undefined, and is populated when you use body-parsing middleware such as express.json() or express.urlencoded().
You don't seem to have loaded the JSON body-parsing middleware.
Second, you said mode: "no-cors" which tells fetch to silently ignore any attempts to do anything which would require permission from CORS.
This includes setting the Content-Type: application/json header which is needed to trigger the JSON parsing middleware.
So remove mode: "no-cors" and add the cors middleware to your server-side code.
Related
Can someone help me understand why it should have the config for this? What was headers or authorization does? Why should I put it as a second parameter?
dispatch({ type: 'FETCH_REQUEST' });
let config = {
headers: { authorization: `Bearer ${userInfo.token}` },
};
//Fetching the data from the backend
const { data } = await axios.get(`/api/orders/${orderId}`, config);
The header is essentially the header of the HTTP request. You need it for special config like authentication key, XSSR token, and other special config which you can read more in that link. The authorization is a authorization token. This is usually the JWT token that you got from the server when you've finished the authentication process. You can read more on the JWT authentication process here. Once you got the authorization token in your header of your request and send it to your server, your server will read in this token, deserialize it to get the data and determine if your HTTP request are valid and return the data. If your token is not valid, the server will throw an 403 (Unauthorize) error.
axios() has a whole number of ways you can specify the request you want.
For example, you can specify just a config object:
// Send a POST request
axios({
method: 'post',
url: '/user/12345',
data: {
firstName: 'Fred',
lastName: 'Flintstone'
}
});
Where the config object contains the method, url and other necessary options.
For all other types of requests, the config object is optional and is only needed if you need to specify some argument other than the URL or the data to send.
For example, with axios.get(), you can use either axios.get(someUrl) or axios.get(someUrl, config). The config object can contain all the options listed here in the doc. Among those options are custom headers, data to append to the URL (for a GET request), options for timeout, sending of credentials, basic auth, progress callbacks, etc....
All these options in the config object are optional. You only need to specify the ones that your particular request requires.
In the code example you show in your question:
let config = {
headers: { authorization: `Bearer ${userInfo.token}` },
};
//Fetching the data from the backend
const { data } = await axios.get(`/api/orders/${orderId}`, config);
This is specifying a custom header for the request that contains an authorization token that is presumably required by the server for this particular type of request so that in the headers of the http request, it will add something like this:
Authorization: Bearer someTokenValueHere
You can read about the authorization header here.
I looked some similar questions but mine seems to be different, because it works with postman but it doesn't work with my own fetch - so there's nothing wrong in my backend I think.
This is my frontend:
url = "http://localhost:8081/signup";
op = {
method: "POST",
credentials: 'same-origin',
mode: 'cors',
headers:{
'Content-type': 'application/x-www-form-urlencoded',
'Accept':'application/json'
},
body:JSON.stringify({
user:'myUser',
password:'myPassword123',
email:'myemail#hotmail.com'
}),
};
fetch(url,op)
.then(dados=>dados.json())
.then(dados=>console.log(dados))
You see? I was careful to use x-www-form-urlencoded because i'm using a middleware in nodejs that works with urlencoded:
app.use(bodyParser.urlencoded({extended:false}));
app.use(bodyParser.json());
In my fetch request, I was also careful to use what I just learned and I hope I learned right:
credentials: same-origin - because it is running in my localhost, so it's from the same origin and also I want to be able to get the cookies. If it belonged in another origin and I also wanted the cookies I would use include.
Mode: cors - I thought I should use this just to get data from other origin, but since didn't work with no-cors (returned lots of weird things) i'm using cors.
Here goes My code (the part that matters), but I don't think it's my backend because it worked with postman:
const express = require("express");
const app = express();
bodyParser = require("body-parser");
app.use(bodyParser.urlencoded({extended:false}));
app.use(bodyParser.json());
const cors = require("cors");
app.use(cors())
app.post("/signup",function(req,res){
if(!req.body.email || !req.body.user|| !req.body.password){
const resultado = {
Empty: "Yes",
Email: req.body.email,
User: req.body.user,
Password: req.body.password,
}
res.json(resultado)
exit()
}
tabelaUsuario.create({
user: req.body.user,
email: req.body.email,
password: req.body.password
}).then(()=>{
req.session.email = req.body.email;
res.json(req.body)
}).catch((erro)=>{
res.send("ERRO! erro: "+erro);
})
})
app.listen(8081);
bodyParser = require("body-parser");
app.use(bodyParser.urlencoded({extended:false}));
app.use(bodyParser.json());
You have body parsing middleware for both JSON and URL encoded bodies.
(Note that body-parser is a dependency of Express and is exposed through the Express API. You don't need to require it explicitly.)
headers:{
'Content-type': 'application/x-www-form-urlencoded',
In your request you tell the server you are sending URL encoded data.
This will trigger the URL encoded body parsing middleware.
body:JSON.stringify({
user:'myUser',
Then you send JSON.
This isn't URL encoded, so the URL encoded body parsing middleware can't parse it.
You need:
To post data encoded in some format
To have a content-type request header that matches that format
To have a body parsing middleware which supports that format
You failed at the middle part.
You need to either:
Send URL encoded data or
Change the content type to say you are sending JSON encoded data
i got a js request to my postgresql database, i'm trying to make a registration.
I tried to send react state before that, but now i just filled it up with constant values.
It send an empty body. Body: null. GET request works, the problem happens only when i use POST request
const response = await fetch("http://localhost:8080/api/user", {
method: "POST",
mode: 'no-cors',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
"username": "lpkopjp",
"email": "mimiomo#mail.ru",
"password": "12345678",
"repeat_password": "12345678"
})
})
UPD: the problem was solved, i've installed cors package and added app.use(cors()); into my backend code (node.js). also you have to delete no cors mode
I'm having problems with cookie authentication between an expressJS server and a VueJS font-end.
When logging in through the site, I successfully get a HTTPOnly Cookie in the set-cookie header:
Screenshot (Ignore the Auth header, using it for testing only)
I also see the cookie in the devTools, and everything looks right too me, I'm not an expert on cookies though so it may not be correct
The problem is when I request the user's settings on another endpoint, the cookie is not sent to the server. The req.cookie object is empty when the this request is handled on the server side.
Here is my fetch code:
const loginOptions = {
method: 'POST',
mode: 'cors',
cache: 'no-cache',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
email: email,
password: password,
}),
credentials: 'same-origin',
};
const settingsOptions = {
method: 'GET',
mode: 'cors',
cache: 'no-cache',
headers: {
'Content-Type': 'application/json',
},
credentials: 'same-origin',
};
const loginResponse = await fetch(baseUrl + '/login', loginOptions);
const userSettings = await fetch(baseUrl + '/settings', settingsOptions);
I've tried using credentials: "include", without success.
On the express server I'm using cors like this:
app.use(cors({
origin: '*',
credentials: true,
}));
Here is also an example of the second request, the 403 status is set by the server when no cookie is attached to the request.
I've tried setting the domain of the cookie to both localhost and 127.0.0.1 as suggested in another thread. I have left it on localhost for now.
Solved
I had read somewhere that you should add a specific domain value to the cookie when creating it. If I just removed that setting, it sets it automatically I'm guessing, and then it worked! So my guess is that I had set the domain value to the wrong value for what I was trying to do
Your response has access-control-allow-origin: http://localhost:8080 which implies you are making a cross-origin request.
You said:
credentials: 'same-origin',
… which tells your client-side code to only include credentials for same-origin requests.
I read somewhere that Chrome wasn't friendly with cookies and localhost env, maybe it could be that.
https://bugs.chromium.org/p/chromium/issues/detail?id=56211
Furthermore, I had some problems with cookies, express and vueJS some times ago.
Maybe it can help you: SetCookie header not stored
I had read somewhere that you should add a specific domain value to the cookie when creating it. If I just removed that setting, it sets it automatically I'm guessing, and then it worked! So my guess is that I had set the domain value to the wrong value for what I was trying to do
This is my first time using axios and I have encountered an error.
axios.get(
`http://someurl.com/page1?param1=1¶m2=${param2_id}`
)
.then(function(response) {
alert();
})
.catch(function(error) {
console.log(error);
});
With the right url and parameters, when I check network requests I indeed get the right answer from my server, but when I open console I see that it didn't call the callback, but instead it caught an error.
Error: Network Error
Stack trace:
createError#http://localhost:3000/static/js/bundle.js:2188:15
handleError#http://localhost:3000/static/js/bundle.js:1717:14
If Creating an API Using NodeJS
Your Express app needs to use CORS (Cross-Origin Resource Sharing). Add the following to your server file:
// This should already be declared in your API file
var app = express();
// ADD THIS
var cors = require('cors');
app.use(cors());
For fuller understanding of CORS, please read the Mozilla Documentation on CORS.
my problem was about the url I was requesting to. I hadn't inserted http:// at the beginning of my url. I mean I was requesting to a url like 92.920.920.920/api/Token instead of http://92.920.920.920/api/Token. adding http:// solved my problem.
It happens when you work on localhost and forgot to add http://
Wrong Usage
const headers = {
"Content-Type": "application/json",
Authorization: apiKey,
};
const url = "localhost:5000/api/expenses/get-expenses";
axios.get(url, { headers });
// NETWORK ERROR
The correct one is
const headers = {
"Content-Type": "application/json",
Authorization: apiKey,
};
const url = "http://localhost:5000/api/expenses/get-expenses";
axios.get(url, { headers });
// WORKS FINE IF YOU HANDLED CORS CORRECTLY IN THE SERVER SIDE
In addition to #jacobhobson answer, I had also used some parameters to made it work.
app.use(cors({origin: true, credentials: true}));
I was having same issue on production on digital ocean droplet. I was using axios in ReactJS to call Node.js API.
Although I included cors
const cors = require('cors');
app.use(cors());
But I still had to add
res.header( "Access-Control-Allow-Origin" );
before calling out my controller. And it worked for me. There I realized that cors is not working properly. So I uninstalled and installed them again and It Works!
Complete code is here.
So either you use
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
res.header("Access-Control-Allow-Headers", "x-access-token, Origin, X-Requested-With, Content-Type, Accept");
next();
});
or use
app.use(cors());
It's the same.
I received a network error with axios 0.27.2 when I was trying to upload an image to our server. After I set headers like below no error is received.
headers:{"Accept":"application/json, text/plain, /","Content-Type": "multipart/form-data"}
and you need to check with your api request's body type in your collection like if it's form-data or x-wwww-form-urlencoded or ..etc.
Make sure you have the same port number in cors({ origin : [ "http://localhost:3001"]}) and the .env file.
In my case I used "https" instead of "http", check that too.
I just want to let you know that after searching for a solution for two days, I was able to solve my error.
Since the proxy was the source of the issue, I must configure a proxy in the package.json file, and I have to follow these instructions in the function that uses Axios:
try { await axios.post("user/login", formData).then((res) => { console.log(res.data); }); } catch (error) { console.log(error.response.data.message); }
and in package.json file need to add a proxy:
"proxy": "http://localhost:6000",
for better understand check this documentation: enter link description here
If you are running react native in development while using real device connected via USB(and the API server is being accessed via development machine IP), ensure the development machine and the device are both connected to the same network
This is happening because of restrict-origin-when-cross-origin policy.Browser sends a pre-flight request to know whom the API server wants to share the resources.
So you have to set origin there in API server and send some status.After that the browser allow to send the request to the API server.
Here is the code.I am running front-end on localhost:8000 and api server is running on port 6000.
const cors = require("cors");
app.options("*", cors({ origin: 'http://localhost:8000', optionsSuccessStatus: 200 }));
app.use(cors({ origin: "http://localhost:8000", optionsSuccessStatus: 200 }));
I have set origin as my front-end url, If You set it to true , then it will allow only port 8000 to access rosource, and front-end running on port 8000 can not access this resource. Use this middleware before route in api server.
I have resolved my issue by adding this header.
var data = new FormData();
data.append('request', 'CompaniesData');
var config = {
method: 'post',
url: baseUrl, headers:{"Accept":"application/json, text/plain, /","Content-Type": "multipart/form-data"},
data : data
};
axios(config)
.then(function (response) {
console.log(JSON.stringify(response.data));
})
.catch(function (error) {
console.log(error);
});
i'm using axios in react-native as android and .net as backend, i have same issue but i can't solve the problem. I think it is security problem when i type the url in chrome it warns me about that in emulator.
axios("http://10.0.2.2:5001/api/Users/getall")
.then((result) => setUsers(result.data.data))
.then((json) => {
return json.data;
})
.catch((error) => {
console.error(error);
})
.then((response) => response.parse());
In my case, I'm using Hapi.js as the backend, so all I had to do is set the cors value to true as in the code below;
const server = Hapi.server({
port: 4000,
host: 'localhost',
state: {
strictHeader: false
},
routes: {
cors: true
}
});
change the port number of your node server.
It took more than 3 hours to solve this error. Solution ended with changing port numer which was initially set to 6000, later set to 3001. Then it worked. My server localhost base url was:
"http://localhost:6000/data"
I changed port number in app.listen() on server and from frontend I call that GET route in async function as
await axios.get('http://localhost:3001/data').
It is working fine now.
If you face the address issue: address already in use :::#port
Then on command prompt: killall -9 node