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
The problem turned out to be PM2, not the API or nginx.
I uninstalled and reinstalled PM2 and now it works :-/
Solution 1:
You can try adding the following headers in the block where you return a response.,
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.,
In your Nginx config, after proxy_pass in the location… Add this below for both servers