Cross-Origin Request Blocked with React and Express
Solution 1
There's a node package called cors which makes it very easy.
$npm install cors
const cors = require('cors')
app.use(cors())
You don't need any config to allow all.
See the Github repo for more info: https://github.com/expressjs/cors
Solution 2
One reason might be you're using the route as localhost:8000 rather than http://localhost:8000.
USE
http://localhost:8000
DON'T USE
localhost:8000
Solution 3
if you add this header
res.setHeader('Access-Control-Allow-Origin', '*');
you're using credential mode (means you're sending some authentication cookie from your app) and as for CORS specification you cannot use the wildcard * in this mode.
you should change your Access-Control-Allow-Origin
header to match the specific host who generated the request
you can change this line:
res.header('Access-Control-Allow-Origin', '*');
to
res.header('Access-Control-Allow-Origin', 'the ip address');
but to be more generic, something like this should work:
res.setHeader('Access-Control-Allow-Origin', req.header('origin')
|| req.header('x-forwarded-host') || req.header('referer') || req.header('host'));
in addition you have even to allow OPTIONS requests from the browser otherwise you will get a preflight request error.
res.setHeader('Access-Control-Allow-Methods', 'POST, OPTIONS');
Solution 4
To anyone else that this may help, I was using axios
with withCredentials: true
.
On my Express backend, I was simply doing,
app.use(cors())
What fixed it was either removing withCredentials: true
from the React frontend or changing my backend to,
app.use(cors({ credentials: true }))
Alex Ironside
Updated on March 03, 2021Comments
-
Alex Ironside about 3 years
So I hit this error, when I was trying to send data to the back end using React. From what I learnt I need to allow the communication on the back-end and in the
.htaccess
file. Here are some of the links I used:No 'Access-Control-Allow-Origin' - Node / Apache Port Issue
How does Access-Control-Allow-Origin header work?
Both of them have code, but it didn't help.
So far my Server-side code is this:
app.use(function (req, res, next) { // Website you wish to allow to connect // res.setHeader('Access-Control-Allow-Origin', 'http://localhost:3000'); res.setHeader('Access-Control-Allow-Origin', '*'); // Request methods you wish to allow res.setHeader('Access-Control-Allow-Methods', 'POST'); // Request headers you wish to allow res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type'); // Set to true if you need the website to include cookies in the requests sent // to the API (e.g. in case you use sessions) res.setHeader('Access-Control-Allow-Credentials', true); // Pass to next layer of middleware next(); });
This is my Client-side code:
sendMail(e) { e.preventDefault(); var name = document.getElementById('name').value; var contactReason = document.getElementById('contactReason').value; var email = document.getElementById('email').value; var additionalInfo = document.getElementById('additionalInfo').value; var body = { name: name, contactReason: contactReason, email: email, additionalInfo: additionalInfo, }; console.log(JSON.stringify(body)); fetch('http://localhost:4000/', { method: 'POST', body: body, }).then(r => console.log(r)).catch(e => console.log(e)); }
So what am I missing? I do not have an
.htaccess
file, but I'm doing it all locally so I'm not sure if I can even use it.It looks to me like I'm allowing all I need, but I guess it's not enough.
If you're going to mark as a duplicate, please at least make sure my issues are covered by the answer.
-
Alex Ironside almost 6 yearsShould I create an
OPTIONS
object or something like this? -
Peter Wilson almost 6 yearsNo, just include it in the express header like shown above
-
Alex Ironside almost 6 yearsNo luck then. Any idea what the other problem might be?
-
Alex Ironside almost 6 yearsSorry I simply put the middleware in the wrong place. Thank you for the help anyway!
-
yankeedoodle almost 3 yearsthe browser should interpret these the same
-
Rakesh K almost 3 yearsThis is what exactly we need to do to get it to work :)