React JS NodeJS CORS Error hosted on DigitalOcean Droplet with NginX reverse proxy front end

Issue

This Content is from Stack Overflow. Question asked by aht2000

I am stuck for two complete days with this problem. I read a lot about it, and tried several things. The good side is that I think I now understand what CORS is about, but the bad side is that the issue is still there.

My PROD environment:

  • Hosted droplet on digital ocean. Installed NginX as reverse proxy to direct the incoming traffic over https (default port 443) to an internal “React Server” running using command “serve -s build” and listening on port 3000.
  • The React server talks to a nodeJS server running on the same droplet listening on port 3500
  • The nodeJS server takes care of interfacing with an external mongoDB.

My Dev environment:

  • The same as above but running on my Windows laptop using VSCode, and http instead of https.
  • No CORS issues faced.

What is the issue:

  • Running the PROD environment and accessing it from my browser returns a CORS error.
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:3500/employees. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing). Status code: 500.

What did I try:

  • Based on my understanding from reading about CORS, I understood that it will be most probably a server side issue (The NodeJS running on port 3500 is not handling CORS properly).
  • I checked multiple time how CORS is implemented, and compared to all the recommendations and answers over the internet, and I seemed to be doing the right thing.
  • So, I thought of using cURL while enforcing it to provide an “Origin” in its request and see.
  • I ran the following two commands from ssh on the droplet command line with the results.
 ===================================

 curl -H "Origin: http://localhost:3000" -v  http://localhost:3500/employees/firstname/Arth; echo
 
 ===================================

*   Trying 127.0.0.1:3500...
* Connected to localhost (127.0.0.1) port 3500 (#0)
> GET /employees/firstname/Arth HTTP/1.1
> Host: localhost:3500
> User-Agent: curl/7.81.0
> Accept: */*
> Origin: http://localhost:3000
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< X-Powered-By: Express
< Access-Control-Allow-Credentials: true
< Access-Control-Allow-Origin: http://localhost:3000
< Vary: Origin
< Content-Type: application/json; charset=utf-8
< Content-Length: 567
< ETag: W/"237-vPb0kecEsX8rIXbwsqXHL/P/Z5w"
< Date: Mon, 19 Sep 2022 07:28:33 GMT
< Connection: keep-alive
< Keep-Alive: timeout=5
<
* Connection #0 to host localhost left intact
[{"_id":"63261071cb56fb978ebfe8bf","firstname":"Arthur","lastname":"Bretherton","email":"abrethertonh@imgur.com","dob":"16/11/1986","age":52,"country":"Thailand","phone":"+66 236 991 7545"},{"_id":"63261071cb56fb978ebfea17","firstname":"Bartholemy","lastname":"Denney","email":"bdenneya1@deliciousdays.com","dob":"09/10/1975","age":48,"country":"China","phone":"+86 721 149 5566"},{"_id":"63261071cb56fb978ebfeb2f","firstname":"Barth","lastname":"Flacknell","email":"bflacknellht@squidoo.com","dob":"22/03/1971","age":44,"country":"China","phone":"+86 880 563 0713"}]

 ==================================

 curl -H "Origin: http://localhost:300" -v  http://localhost:3500/employees/firstname/Arth; echo
 
 ===================================


*   Trying 127.0.0.1:3500...
* Connected to localhost (127.0.0.1) port 3500 (#0)
> GET /employees/firstname/Arth HTTP/1.1
> Host: localhost:3500
> User-Agent: curl/7.81.0
> Accept: */*
> Origin: http://localhost:300
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 500 Internal Server Error
< X-Powered-By: Express
< Content-Type: text/html; charset=utf-8
< Content-Length: 19
< ETag: W/"13-MClrdFoaBMV/BSRr2tsNTknKVAU"
< Date: Mon, 19 Sep 2022 07:29:24 GMT
< Connection: keep-alive
< Keep-Alive: timeout=5
<
* Connection #0 to host localhost left intact
Not allowed by CORS

As seen from the above, when the origin is http://localhost:3000 which is on the white list of my nodeJS CORS Origin array, the call succeed.

const allowedOrigins = require('./allowedOrigins');

const corsOptions = {
    origin: (origin, callback) => {
        console.log('origin: ', origin);
        if (allowedOrigins.indexOf(origin) !== -1 || !origin) {
            callback(null, true)
        } else {
            callback(new Error('Not allowed by CORS'));
        }
    },
    optionsSuccessStatus: 200
}

module.exports = corsOptions;
const allowedOrigins = [
    'https://www.yoursite.com',
    'http://localhost:3000'
];

module.exports = allowedOrigins;

However when I change the port# to be 300 (just to make it not in my whitelist), it fails with the “Not allowed by CORS” error.

I am deducing from the above test that my nodeJS server is acting correctly. Is this the case?

If so, then what do I need to do special on the React side to make it work?

Here is a part of my code on the React side:

const fetchEmployees = async () => {
        try {
          const response = await api.get("/employees");
          setEmployees(response.data);
          );
        } catch (err) {
          showError(err);
        }
      };
      fetchEmployees();
    }

Here is as well the configuration of Nginx in case it comes into play:

        location / {
                # First attempt to serve request as file, then
                # as directory, then fall back to displaying a 404.
#               try_files $uri $uri/ =404;

                proxy_pass http://localhost:3000;
                proxy_buffering off;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-Host $host;
                proxy_set_header X-Forwarded-Port $server_port;
        }



Solution

This question is not yet answered, be the first one who answer using the comment. Later the confirmed answer will be published as the solution.

This Question and Answer are collected from stackoverflow and tested by JTuto community, is licensed under the terms of CC BY-SA 2.5. - CC BY-SA 3.0. - CC BY-SA 4.0.

people found this article helpful. What about you?