Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to send data using fetch and POST request with credentials included?

I want to send some data in JSON from my React front-end on port 3000 using fetch, to my node.js server on 3005. I configured cors on my server, but every time I try to send request with cookies, Chrome throws error:

Access to fetch at 'http://localhost:3005/user-connected' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'.

All console.log's from server code are skipped.

When I delete header in my fetch code

"Content-Type", "application/json"

I get cookies, but without data. With this header included, but without credentials: "include", I can get my data, but I'll never get both at the same time.

Here's my fetch code:

fetch("http://localhost:3005/user-connected", {
            mode: "cors",
            method: "post",
            headers: [
                ["Content-Type", "application/json"],
            ],
            credentials: "include",
            body: JSON.stringify({data: "123"})
        })
            .then(data => data.json())
            .then((data) => {
               console.log(`Response: ${JSON.stringify(data)}`);
            }).catch(err => {
                console.log(`Error: ${err}`)
        });

Node.js cors configuration:

app.use(cors({credentials: true}));

app.use((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', 'X-Requested-With,Content-Type', 'Access-Control-Allow-Origin', 'Origin');
  res.setHeader('Access-Control-Allow-Credentials', true);
  next();
});

And my post route:

let cookiesData = (req, res) => {
  console.log(`Cookie user-connected: ${req.cookies.io}`)


  console.log(`Received data: ${JSON.stringify(req.body)}`);
  res.send({ status: "OK" });
}

router.post("/user-connected", cors({origin: 'http://localhost:3000'}), cookiesData);

Is it even possible to do what I want? Or maybe I missed some important configuration?

like image 245
ytsejam Avatar asked Sep 11 '25 21:09

ytsejam


2 Answers

you need to pass headers like this in your fetch request for post method:

{
  credentials: 'include',
  mode: 'cors',
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
}

You must be sure that you have given access allow origin for localhost:3000

like image 156
Sadhna Rana Avatar answered Sep 13 '25 10:09

Sadhna Rana


Adding a Content-Type will trigger a preflight request first before sending the actual request. Preflight requests method is OPTIONS. OPTIONS doesn't include cookies in the request header (at least for Chrome and Firefox).

The error is probably because of this code:

console.log(`Cookie user-connected: ${req.cookies.io}`)

req.cookies is null during preflight requests and will throw an error when you try to get req.cookies.io. Preflight requests require the server to return 200 (see https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#Preflighted_requests). Your code having errors might be throwing 500 thus showing you the dreaded CORS error message.

You must deal with preflight requests first.

On the server side, try handling the OPTIONS method in your CORS code to return a 200 before next():

app.use((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', 'X-Requested-With,Content-Type', 'Access-Control-Allow-Origin', 'Origin');
  res.setHeader('Access-Control-Allow-Credentials', true);

  if (req.method === 'OPTIONS') {
    res.sendStatus(200);
    return;
  }

  next();
});

This will prevent whatever code next() will execute during preflight requests and will tell the client that it is OK to send the actual request.

like image 30
Christian Joshua Catalan Avatar answered Sep 13 '25 10:09

Christian Joshua Catalan