I am working on a node API with React and Express. Node retrieves the data from Postgress like this:
router.get('/getRestaurants', async(req, res) => {
console.log('Restaurants');
try {
const { rows } = await db.getAllRestaurants();
console.log(rows);
res.json(rows);
} catch(error) {
console.error(`Error ${error}`);
res.status(500).send({message: `API internal error`});
}});
The console.log it shows the data without problem and if I use Postman or Curl it seems to work fine. But when I try to retrieve the data from my frontend React I get this error:
Uncaught (in promise) SyntaxError: JSON.parse: unexpected end of data at line 1 column 1 of the JSON data
React makes the POST request like this:
useEffect(() => {
async function fetchData() {
const response = await fetch('http://172.20.0.4:3000/getRestaurants', {
method: 'GET', // *GET, POST, PUT, DELETE, etc.
mode: 'no-cors', // no-cors, *cors, same-origin
cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
credentials: 'same-origin', // include, *same-origin, omit
headers: {
'Content-Type': 'application/json'
// 'Content-Type': 'application/x-www-form-urlencoded',
},
redirect: 'follow', // manual, *follow, error
referrerPolicy: 'no-referrer', // no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url
});
const data = await response.json();
console.log(data);
return data;
}
fetchData();
});
It's probably not hard to see but there's something I'm missing. Thank you in advance!
CodePudding user response:
I think you have a problem with CORS, since you are fetching data from another origin, you need to set mode: 'cors'
, which means that you will fetch data across origins. when you set it to mode: 'no-cors'
that mean that you don't allow cross origins and that is the cause of the problem. cos as you said. your express app has a different origin than your react app. but it will still not work until you allow your express api, the origin you are fetching from. by setting headers to: ACCESS-CONTROLLE-ALLOW-ORIGIN *
and the star * means allow all kind of origins. but if you want to allow a specific origin, replace the
*
with url of your react app. you can also use a node.js package that will help you at this in a clean and easy way, example using cors package https://github.com/expressjs/cors:
const cors = require("cors");
let whitelist = ["http://localhost:3000"];
// Middleware
app.use(
cors({
origin: function (origin, callback) {
if (!origin) return callback(null, true);
if (whitelist.indexOf(origin) === -1) {
var message =
"The CORS policy for this origin doesnt "
"allow access from the particular origin.";
return callback(new Error(message), false);
}
return callback(null, true);
},
})
);