Cross-Origin Request Blocked with React and Express

42,556

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 }))
Share:
42,556
Alex Ironside
Author by

Alex Ironside

Updated on March 03, 2021

Comments

  • Alex Ironside
    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
    Alex Ironside almost 6 years
    Should I create an OPTIONS object or something like this?
  • Peter Wilson
    Peter Wilson almost 6 years
    No, just include it in the express header like shown above
  • Alex Ironside
    Alex Ironside almost 6 years
    No luck then. Any idea what the other problem might be?
  • Alex Ironside
    Alex Ironside almost 6 years
    Sorry I simply put the middleware in the wrong place. Thank you for the help anyway!
  • yankeedoodle
    yankeedoodle almost 3 years
    the browser should interpret these the same
  • Rakesh K
    Rakesh K almost 3 years
    This is what exactly we need to do to get it to work :)