skip to Main Content

UPDATE 4: When I run the Node app with "yarn start" instead of pm2 I am able to load a blank array as being returned instead of 404 Not Found, still CORS error, but no 404.

UPDATE 3: I’m not sure what exactly is returning error 404. I removed all 404 return errors from my server app to be 406 instead and it still says "404 Not Found" on a blank white page, which means it’s not nginx returning the 404 or it would say so. I’m so confused X-x

UPDATE 2: I am now seeing in the network tab that after the CORS error I am getting "404 Not Found" returned, I think maybe the problem is in my nginx config. I think maybe in the last section as I noticed the Certbot setup a possible return 404, but I can’t seem to find the syntax to add a redirect for the api url.

map $http_upgrade $connection_upgrade {
    default         upgrade;
    ''              close;
}
server {
     
       server_name example.com www.example.com;
       
    add_header 'Access-Control-Allow-Origin' 'https://example.com';
    add_header 'Access-Control-Allow-Credentials' 'true';
    add_header 'Access-Control-Allow-Headers' 'Authorization,Accept,Origin,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range';
    add_header 'Access-Control-Allow-Methods' 'GET,POST,OPTIONS,PUT,DELETE,PATCH';

       location / {
        # Backend nodejs server
        proxy_pass         http://127.0.0.1:3000;
        proxy_http_version  1.1;
        proxy_set_header    Upgrade     $http_upgrade;
        proxy_set_header    Connection  $connection_upgrade;
    }

    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot


}

server {

       server_name api.example.com;

    add_header 'Access-Control-Allow-Origin' 'https://api.example.com';
        add_header 'Access-Control-Allow-Credentials' 'true';
        add_header 'Access-Control-Allow-Headers' 'Authorization,Accept,Origin,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range';
        add_header 'Access-Control-Allow-Methods' 'GET,POST,OPTIONS,PUT,DELETE,PATCH';

       location / {
        # Backend nodejs server
        proxy_pass         http://127.0.0.1:5000;
        proxy_http_version  1.1;
        proxy_set_header    Upgrade     $http_upgrade;
        proxy_set_header    Connection  $connection_upgrade;
    }

    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/api.example.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/api.example.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot



}

server {
    if ($host = www.example.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


    if ($host = example.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


     
       server_name example.com www.example.com;
    listen 80;
    return 404; # managed by Certbot




}

Once again banging my head against the wall trying to setup my NodeJS Api with React App frontend on a VPS server.

I am getting this error
(index):1 Access to XMLHttpRequest at 'https://api.example.com/questions/getTags' from origin 'https://example.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

I’m using the cors middleware in my NodeJS app and have tried all the solutions suggested here:

CORS express not working predictably

Here is my code:

import mongoose from 'mongoose';
import cors from 'cors';
import dotenv from 'dotenv';
import questionRoutes from './routes/questions.js';
import userRoutes from './routes/users.js';


const app = express();
dotenv.config();

app.use(express.json({ limit: "30mb", extended: true}));
app.use(express.urlencoded({ limit: "30mb", extended: true}));
app.use(cors());

app.use('/questions', questionRoutes);
app.use('/user', userRoutes);

const CONNECTION_URL = process.env.CONNECTION_URL;
const PORT = process.env.PORT || 5000;

mongoose.connect(CONNECTION_URL, { useNewUrlParser: true, useUnifiedTopology: true })
    .then(() => app.listen(PORT, () => console.log(`Server Running on port: ${PORT}`)))
    .catch((error) => console.log(error.message));

mongoose.connection
    .once('open', () => console.log('Connected'))
    .on('error', (error)=> {
        console.log("Error: " + error);
    });

mongoose.set('useFindAndModify', false);```

I also tried adding the headers to my nginx config like so…

        add_header 'Access-Control-Allow-Credentials' 'true';
        add_header 'Access-Control-Allow-Headers' 'Authorization,Accept,Origin,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range';
        add_header 'Access-Control-Allow-Methods' 'GET,POST,OPTIONS,PUT,DELETE,PATCH';

but no dice there either.

The cors error is very unhelpful so would really appreciate any advice on where to start troubleshooting.

Thanks

UPDATE: as requested here is my api call in the client.

import axios from 'axios';

const API = axios.create({ baseURL: 'https://api.example.com/' });

API.interceptors.request.use((req) => {
    if(localStorage.getItem('profile')) {
        req.headers.Authorization = `Bearer ${JSON.parse(localStorage.getItem('profile')).token}`;
    }

    return req;
});

API.interceptors.response.use((res) => {
    return res;
}, err => {
    //console.log(err.response.data.message);
    throw new Error(err.response.data.message);
});

export const fetchQuestions = (tagName) => API.post('/questions', tagName);
export const fetchTags = () => API.get('/questions/getTags');

3

Answers


  1. Chosen as BEST ANSWER

    The problem turned out to be PM2, not the API or nginx.

    I uninstalled and reinstalled PM2 and now it works :-/


  2. Solution 1:
    You can try adding the following headers in the block where you return a response.,

    res.header("Access-Control-Allow-Origin", "*")
    res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept")
    

    Solution 2:
    Or you can add these headers for all your responses by using the following code snippet in your app.js or server.js file.,

    app.use(function(req, res, next) {
    res.header("Access-Control-Allow-Origin", "*")
    res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept")
    next() 
    })
    
    Login or Signup to reply.
  3. In your Nginx config, after proxy_pass in the location… Add this below for both servers

    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection 'upgrade';
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-for $remote_addr;
    proxy_cache_bypass $http_upgrade;
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search