MERN simple app CORS error issue - POST request - node.js

I am getting,
Access to fetch at 'http://localhost:9000/api/v1/content' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
and
for my FE(react)
and getting syntax err for BE(node),
SyntaxError: Unexpected token " in JSON at position 0
I have no issue with GET request but I can't POST.
Here is my FE
addContent = async (e) => {
e.preventDefault();
try {
const response = await fetch('http://localhost:9000/api/v1/content', {
method: 'POST',
body: JSON.stringify(this.state.title),
// mode:'cors', --> tried after researching but it didn't solve my issue
headers: {
'Content-Type': 'application/json'
}
});
if(!response.ok) {
throw Error(response.statusText)
}
} catch (err) {
console.log('addContent failed -', err)
}
}
Here is my BE
origin: ['http://localhost:3000', 'https://localhost:3000'],
credentials: true,
optionsSuccessStatus:200
}
app.use(cors(corsOptions));
Also, when I POST with postman, I was able to POST(got 200) however, it only returns _id. there is no body(content title that I want to post)
I read many articles that explained about cors issue but I couldn't find right answer to solve my issue. Please assume me as beginner of programing.. Thank you ahead!!

Try This
addContent = async (e) => {
e.preventDefault();
try {
const response = await fetch('http://localhost:9000/api/v1/content', {
method: 'POST',
body: JSON.stringify(this.state.title),
// mode:'cors', --> tried after researching but it didn't solve my issue
headers: {
'Access-Control-Allow-Origin': '*',
'Content-Type': 'application/json'
}
});
if(!response.ok) {
throw Error(response.statusText)
}
} catch (err) {
console.log('addContent failed -', err)
}
}
And also you can refer https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch
And I suggest try once without using cors at express.
origin: ['http://localhost:3000', 'https://localhost:3000'],
credentials: true,
optionsSuccessStatus:200
}
//app.use(cors(corsOptions));

Your error here, means that you are not allowed to access localhost:9000 from any other URL.
I recommend you take a look at this (https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS)
If you want your API to be accessed by anyone, you can set your "Access-Control-Allow-Origin" header to "*".
Here is a full explanation of this header purpose (https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin).
I hope it will be useful.

Related

unexpected end of data at line 1 column 1 of the JSON data in express with React

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!
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);
},
})
);

CORS ERROR in React js axios when its working in postman

In my Mern Stack Project I am facing a problem when I am creating a Lesson from postman its created successfully but when I am trying from my browser its given me 500 error in network tab. But in console i got CORS error and also 500 error. I am including SS in bellow if anyone can face this kind of problem please help me. I am trying all the similiar solution from stackoverflow.
Access to XMLHttpRequest at 'https://lms-api-v1.coderslab.com.bd/api/v1/lesson/add' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
const apiClient = axios.create({
baseURL: "https://my-link",
withCredentials: false,
accesscontrolalloworigin: "*",
accesscontrolallowMethods: "GET, POST, PUT, DELETE, PATCH, OPTIONS",
});
// Create Lesson
export const createLesson = (lessonData, token) => async (dispatch) => {
try {
dispatch({ type: NEW_LESSON_REQUEST });
const config = {
headers: {
Authorization: `Bearer ${token}`,
'Access-Control-Allow-Origin' : '*',
'Access-Control-Allow-Credentials':true,
'Access-Control-Allow-Methods':'GET,PUT,POST,DELETE,PATCH,OPTIONS',
},
};
const { data } = await apiClient.post(`lesson/add`, lessonData, config);
dispatch({
type: NEW_LESSON_SUCCESS,
payload: data,
});
} catch (error) {
dispatch({
type: NEW_LESSON_FAIL,
payload: error.response,
});
}
};
you need to allow origin from backend. like this
Access-Control-Allow-Origin: http://localhost:3000
Add this in backend
Access-Control-Allow-Origin: '*'

No 'Access-Control-Allow-Origin' policy error on sending POST request to REST API

I am making a simple full-stack project wherein I have a very basic REST API built using NodeJS and Express. It is a server-side rendered website.
While trying to login, when I send a POST request to the login endpoint, I am getting the following error in the console
Access to XMLHttpRequest at 'http://127.0.0.1:3000/api/v1/users/login'
from origin 'http://localhost:3000' has been blocked by CORS policy:
Response to preflight request doesn't pass access control check: No
'Access-Control-Allow-Origin' header is present on the requested
resource.
This is the code snippet that sends the POST request
const login = async (email,password) => {
try {
const res = await axios({
method: 'POST',
url: 'http://127.0.0.1:3000/api/v1/users/login',
data: {
email,
password
}
});
if(res.data.status === 'success') {
alert('Logged in successfully');
window.setTimeout(() => {
location.assign('/');
}, 1500);
}
}
catch(err) {
console.log(err);
}
}
Please explain as to why I'm getting that error and how to fix it. The API is not deployed yet and it's running on localhost
Your request origin is:
http://localhost:3000
This is not the same as the domain you're sending the request to:
http://127.0.0.1:3000
To avoid this CORS error, the FQDN must be the same, including hostname and port. (Or you could configure your server for CORS.) As far as the server is concerned, the different host means a completely separate entity, even if it's the same machine.
Change your url to:
url: 'http://localhost:3000/api/v1/users/login',
could you add Access-Control-Allow-Origin header to the request and see ,
const login = async (email,password) => {
try {
const res = await axios({
method: 'POST',
url: 'http://127.0.0.1:3000/api/v1/users/login',
headers: {
'Access-Control-Allow-Origin': '*',
'Content-Type': 'application/json',
},
data: {
email,
password
}
});
if(res.data.status === 'success') {
alert('Logged in successfully');
window.setTimeout(() => {
location.assign('/');
}, 1500);
}
}
catch(err) {
console.log(err);
}
}

Access-Control-Allow-Origin error when trying to invoke Firebase Functions (Even using firebase's example code!)

Please read, this is different!
I've used Firebase Functions previously and solved this issue by adding this code:
const cors = require('cors')({ origin: true });
return cors(req, res, () => {
let format = req.query.format;
if (!format) {
format = req.body.format;
}
const formattedDate = moment().format(format);
console.log('Sending Formatted date:', formattedDate);
res.status(200).send(formattedDate);
});
But now I'm working on a new project, and I'm getting this error no matter what I try to do.
I have read and tried the solutions in over 20 other questions here on stackoverflow and around the internet, and none of them work now.
So I went to firebase's GitHub, downloaded the date example (has the recommended cors fix implemented) and deployed it.
And I still get the same error!
Access to fetch at 'https://us-central1-generation-y-members.cloudfunctions.net/date' from origin
'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
The function can be called from postman and does work. https://i.imgur.com/YTi1PpQ.png
I've upgraded my project to the blaze plan (didn't help).
I've tried changing to origin: "http://localhost:3000" instead of origin: true, didn't help at all.
I've tried uploading my react app to a server and calling from there, same result (http, not https) - even when setting origin: "http://my-site.com"
Any pointers would be highly appreciated.
The issue is that the query being made from the localhost is missing the CORS headers.
On your client side application you need to add the following headers to be able to perform the CORS calls.
'Access-Control-Allow-Origin', '*'
'Access-Control-Allow-Headers', 'Content-Type'
If you are using jav ascript on the client side application this can be done with the following code, according to the libraries you are using.
xhr.setRequestHeader('Access-Control-Allow-Origin', '*');
xhr.setRequestHeader('Access-Control-Allow-Headers', 'Content-Type');
I found the solution so I'll post it here for anyone that has the same error and doesn't know why it's happening:
This is the code I'm using now, the issue was not using JSON.stringify() when setting the body for the request.
let body: any = {};
body.name = currentUser.name;
body.email = currentUser.email;
body.password = generatedPassword;
body.message = '';
body.number = randomNumber;
const requestOptions: any = {
method: 'POST',
mode: 'cors',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(body), // ISSUE WAS HERE! I HAD 'body: body'
};
try {
let response = await (await fetch('https://us-central1-generation-y-members.cloudfunctions.net/register', requestOptions)).text();
// let response = await (await fetch('http://localhost:5001/generation-y-members/us-central1/register', requestOptions)).text();
console.log({ response: response });
sentEmails.push(currentUser.email);
} catch (e) {
console.log({ error: e });
}
Good luck!

POST request from React to Node.js

I don't know why this happens.
When I'm making a request to my server in Node.js and when it's GET then I can get a response. It looks like that:
fetch(config.apiUsersURL, {
method: "GET",
headers: {
"Content-Type": "application/json"
},
credentials: "same-origin",
mode: 'no-cors'
})
.then(res => this.setState({
isConected: true
}))
.catch(error => error);
When I'm requesting to the same url but with POST I'm getting nothing. Am I missing something?
const ObjToSend = { isReady: true };
fetch( config.apiUsersURL, {
method: 'POST',
mode: 'no-cors',
body: JSON.stringify(ObjToSend),
headers: {
"Content-Type": "application/json"
},
credentials: "same-origin",
mode: 'no-cors',
})
.then(res => res.json())
.then(r => this.setState({ questions: r }))
My endpoint looks like that:
let randomProblem2;
router.post('/', (req, resp) => {
resp.append('Access-Control-Allow-Origin', '*')
resp.append('Access-Control-Allow-Headers', 'Content-Type')
console.log("this shows if yes was clicked", req.body)
if(req.body.isReady){ //when clicked
randomProblem2 = problemManager.getRandomProblem();
randomize(randomProblem2, resp);
}
})
function randomize(randomProblem2, resp){
resp.json({
randomProblem : randomProblem2
}
)}
Since the mode you are using is no-cors, you cannot use javascript to access the response
Quoted below from MDN:
no-cors — Prevents the method from being anything other than HEAD, GET
or POST, and the headers from being anything other than simple
headers. If any ServiceWorkers intercept these requests, they may not
add or override any headers except for those that are simple headers.
In addition, JavaScript may not access any properties of the resulting
Response. This ensures that ServiceWorkers do not affect the semantics
of the Web and prevents security and privacy issues arising from
leaking data across domains.
Kindly check the MDN link below for the rest of mode options
https://developer.mozilla.org/en-US/docs/Web/API/Request/mode

Resources