ReactJS NodeJS CORS Request Not Succeeded calling NodeJS https API - node.js

My reactjs website runs on https and my NodeJS server is https but I got error calling the NodeJS api from reactjs website. Both ReactJS website and NodeJS api deployed on the same linux VPS server, my database is on a remote but the connection is fine as I am not getting database connection error but i got cors errors like below:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://localhost:8184/api/v1/signin. (Reason: CORS request did not succeed). Status code: (null).
My NodeJS that started the https server enable cors and it allowed cross origin. See my NodeJS
const cors = require('cors')({
origin: 'https://mydomaindotcom'
});
const allowCrossDomain = function (req, res, next) {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'POST, GET, PUT,PATCH, DELETE, OPTIONS, ');
res.header('Access-Control-Allow-Credentials', false);
res.header('Access-Control-Max-Age', '86400');
res.header('Access-Control-Allow-Headers', 'Authorization, X-Requested-With, X-HTTP-Method-Override, Content-Type, Accept');
next();
};
app.use(allowCrossDomain);
// Error logger
app.use(logger('dev', {
skip: function (req, res) { return res.statusCode < 400 },
stream: fileWriter
}))
app.use(logger('dev'));
app.use(bodyParser.urlencoded({extended: false}));
app.use(bodyParser.json());
app.use(cors);
app.use(fileUpload());
app.use("/api/v1", routes);
In my ReactJS package.json file i have my domain as homepage like below:
"homepage": "https://mydomain",
"Hostname": "https://mydomain",
Please help on this cors errors, it has taken enough sweat on my face.

Related

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https:// 2020 node js

There are so many questions asked based on this issue but none solves my problem.
I am using cloud9 IDE for my development. I am trying to receive data from node server to angular project using a API. My node.js server has all the CORS header required. But I continue to receive the error.
Here is my server code:
var express = require('express'),
app = express(),
port = 8080,
bodyParser = require('body-parser');
const cors = require('cors');
app.use(cors());
const { expressCspHeader, INLINE, NONE, SELF } = require('express-csp-header');
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(expressCspHeader({
policies: {
'default-src': [expressCspHeader.NONE],
'img-src': [expressCspHeader.SELF],
}
}));
app.use(cors());
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header('Access-Control-Allow-Methods', 'GET');
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
if ('OPTIONS' == req.method) {
res.sendStatus(200);
}
else {
next();
}});
var routes = require('./api/routes/doRoutes'); //importing route
routes(app);
app.use(function(req, res) {
res.status(404).send({url: req.originalUrl + ' not found'});
});
app.listen(port);
console.log('RESTful API server started on: ' + port);
Here is the error on firefox browser:
Is it the IDE thats causing the problem? Or am i missing out on something? Please help !
I think it's because you only have the get verb enabled in your backend
Change this:
res.header('Access-Control-Allow-Methods', 'GET');
for this:
res.header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, DELETE');

How to get ExpressJs API CORS set up properly

I have a Single Page Application(SPA) using axios that tries to get information from a ExpressJS Api running on the same server.
In the SPA axios settings I have the following:
headers: {
'Access-Control-Allow-Origin': '*',
'Authorization': store.getters.token,
'user': store.getters.user
},
and in the API i am using the npm package cors like this:
const express = require('express');
const path = require('path');
const cookieParser = require('cookie-parser');
const logger = require('morgan');
const cors = require('cors');
const app = express();
app.use(logger('dev'));
app.use(express.json());
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use(cors());
const indexRouter = require('./routes/index');
const adminRouter = require('./routes/adminRoute');
// More routes
app.use('/api', indexRouter);
app.use('/api/admin', adminRouter);
app.use('/api/user', userRouter);
// using more routes
This works fine when running locally, but when putting the api on a server (using a node application) I get CORS errors:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at mysite.com. (Reason: CORS request did not succeed).
I can access the api directly from browser and get a response without problems (since it isn't using cross reference) but at least I know the API is running.
I have tried creating the following (before I define my routes) instead without success:
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();
});
What am I doing wrong?
It's really strange, to allow anything you have to just write app.use(cors()) and it should work probably now it dont work because after app.use(cors()) you write:
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();
});
then you should try with just cors() middleware. In order to set cors properly check cors`s documentation.
Documentation
The reason why this did not work was because the web hotel where I hosted my ExpressJS api had not set up their nginx web server proxy so that it could accept the OPTIONS request properly and return with Access-Control-Allow-Origin: api.site.com
If you need more information regarding the setup of cors have a look at these links
CORS express not working predictably
How do I host a web application and an API from the same server while keeping them in separate?
Why doesn't adding CORS headers to an OPTIONS route allow browsers to access my API?
https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#Preflighted_requests

Node JS - CORS Issue Response to preflight request doesn't pass access control check: The value of the 'Access-Control-Allow-Origin' header

I'm running an issue with my Angular 2 web app.
On Node JS server side, I got an issue with CORS preflighting.
I want to upload a file on the server, and when I do it, I have this issue :
XMLHttpRequest cannot load http://localhost:4000/upload. Response to preflight request doesn't pass access control check: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. Origin 'http://localhost:3000' is therefore not allowed access. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.
where localhost:4000 is my server and localhost:3000 is my client.
My server.js file is like this :
require('rootpath')();
var express = require('express');
var app = express();
var cors = require('cors');
var bodyParser = require('body-parser');
var expressJwt = require('express-jwt');
var config = require('config.json');
var multer = require('multer');
app.use(cors());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
// // use JWT auth to secure the api
app.use(expressJwt({ secret: config.secret }).unless({ path: ['/users/authenticate', '/users/register'] }));
// // routes
app.use('/users', require('./controllers/users.controller'));
app.use('/challenges', require('./controllers/challenges.controller'));
// NEW UPLOAD
app.use(function(req, res, next) { //allow cross origin requests
res.setHeader("Access-Control-Allow-Methods", "POST, PUT, OPTIONS, DELETE, GET");
res.header("Access-Control-Allow-Origin", "http://localhost:3000");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
res.header("Access-Control-Allow-Credentials", true);
next();
});
/** Serving from the same express Server
No cors required */
app.use(express.static('../client'));
app.use(bodyParser.json());
var storage = multer.diskStorage({ //multers disk storage settings
destination: function (req, file, cb) {
cb(null, './uploads/');
},
filename: function (req, file, cb) {
var datetimestamp = Date.now();
cb(null, file.fieldname + '-' + datetimestamp + '.' + file.originalname.split('.')[file.originalname.split('.').length -1]);
}
});
var upload = multer({ //multer settings
storage: storage
}).single('file');
/** API path that will upload the files */
app.post('/upload', function(req, res) {
upload(req,res,function(err){
console.log(req.file);
if(err){
res.json({error_code:1,err_desc:err});
return;
}
res.json({error_code:0,err_desc:null});
});
});
// FIN NEW UPLOAD
// start server
var port = process.env.NODE_ENV === 'production' ? 80 : 4000;
var server = app.listen(port, function () {
console.log('Server listening on port ' + port);
});
The weirdest thing is that, when I remove the following part, the upload is working :
app.use(cors());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
// // use JWT auth to secure the api
app.use(expressJwt({ secret: config.secret }).unless({ path: ['/users/authenticate', '/users/register'] }));
// // routes
app.use('/users', require('./controllers/users.controller'));
app.use('/challenges', require('./controllers/challenges.controller'));
But then, I got other issues :
(I did not include http prefix before localhost due to reputation)
1) zone.js:2019 OPTIONS localhost:4000/users 404 (Not Found)
2) XMLHttpRequest cannot load localhost:4000/users. Response for preflight has invalid HTTP status code 404
3) EXCEPTION: Response with status: 0 for URL: null
4) Uncaught Response {_body: ProgressEvent, status: 0, ok: false, statusText: "", headers: Headers…}
I think we have to fix the cors() part in the first example but I don't know what to really do.
Thanks
UPDATE : After modifying with your code, I'm running a new issue :
XMLHttpRequest cannot load localhost:4000/users. Request header field Authorization is not allowed by Access-Control-Allow-Headers in preflight response
and when I try to upload my file, I got a new issue :
POST localhost:4000/upload 401 (Unauthorized)
I tried to add many origins in an array instead of only localhost:3000, but nothing changes.
Anything else : if I add "Origin","Content-Type","Accept" to the list of headers, I have this following error :
OPTIONS localhost:4000/users net::ERR_CONNECTION_REFUSED.
I got to admit CORS is a bit difficult.
According to the cors docs, https://github.com/expressjs/cors, to enable CORS Pre-Flight you should add the following code:
app.options('*', cors()) // include before other routes
You can also enable it for specific routes:
app.options('/products/:id', cors()) // enable pre-flight request for DELETE request
app.del('/products/:id', cors(), function (req, res, next) {
res.json({msg: 'This is CORS-enabled for all origins!'})
})

How to manage CORS policy properly in express?

I am trying to allow access from everywhere.
I have tried using app middleware:
app.use(function (req, res, next) {
res.setHeader("Access-Control-Allow-Origin", "*");
res.setHeader('Access-Control-Allow-Methods', '*');
res.setHeader("Access-Control-Allow-Headers", "*");
next();
});
I have tried using it in the route:
app.post('/login',function(req,res){
var login = req.body;
var sess = req.session;
if (!login.email && !login.pwd){
return res.status(401);
}
res.header("Access-Control-Allow-Origin", '*');
res.header("Access-Control-Allow-Headers", '*');
.... more code here
Both do not work. I keep getting an error: "Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource."
Further down the server, we use similar code for another route, which works:
app.post('/questar',function(req,res){
//allow xhr post from retireup domains
var cors = {
origin: "https://www.website.com";
};
res.header("Access-Control-Allow-Origin", cors.origin);
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
res.type('application/json');
I cannot tell the difference between the code, but only one set works. Any ideas why? This seems like an issue that shouldn't be so complicated. Thanks
After applying "cors" middleware. You should be passed "http://" before "localhost:". in url send to by Axios like this:
axios.get("http://localhost:8080/api/getData")
.then(function (response) {
this.items= response.data;
}).catch(function (error) {
console.log(error)
});
MDN has a very short explanation on how a server should respond to a Preflight Request.
You handle CORS preflight requests by handling the HTTP OPTIONS method (just like you would handle GET and POST methods) before handling other request methods on the same route:
app.options('/login', ...);
app.get('/login'. ...);
app.post('/login'. ...);
In your case, it might be as simple as changing your app.use() call to app.options(), passing the route as the first argument, setting the appropriate headers, then ending the response:
app.options('/login', function (req, res) {
res.setHeader("Access-Control-Allow-Origin", "*");
res.setHeader('Access-Control-Allow-Methods', '*');
res.setHeader("Access-Control-Allow-Headers", "*");
res.end();
});
app.post('/login', function (req, res) {
...
});
Configure the CORS stuff before your routes, not inside them.
Here, like this (from enable-cors.org):
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();
});
app.get('/', function(req, res, next) {
// Handle the get for this route
});
app.post('/', function(req, res, next) {
// Handle the post for this route
});
I always configure it like this in my Express+Angular apps and it works just fine.
Hope it helps.
First install, the "cors" package from npm: npm i -S cors
Then enable it in your express server.
var express = require('express'),
cors = require('cors');
const app = express();
app.use(cors());
...
Following some standard node projects out there, below CORS configuration worked for me always. It requires the npm package 'cors'. Note: Origin * means enabling responses to any origin and replies with status code 200. If this needs to be limited to one domain, update the origin accordingly. Ex: [origin: 'http://exampleui.com']
var cors = require('cors');
var corsOptions = {
origin: '*',
optionsSuccessStatus: 200,
}
app.use(cors(corsOptions));
app.use(express.json())
Following other's answers, this worked for me:
res.setHeader("Access-Control-Allow-Origin", 'http://myDomain:8080');
res.setHeader('Access-Control-Allow-Methods', 'POST,GET,OPTIONS,PUT,DELETE');
res.setHeader('Access-Control-Allow-Headers', 'Content-Type,Accept');
All you have to whitelist the domains name to avoid getting cors error messages.
There is a plugin called cors, installed it into your project using this command
npm i cors
after installing use this code to remove the cors related errors form your project.
const cors = require('cors');
const corsOption = {
credentials: true,
origin: ['http://localhost:3000', 'http://localhost:80']
}
app.use(cors(corsOption));
In the origin section you can pass any domain to whitelist it. If you want to whitelist all the domain names, instead of passing the the urls array. you can pass '*' over there.
Example : origin: '*'
credentials: Configures the Access-Control-Allow-Credentials CORS header. Set to true to pass the header, otherwise it is omitted.

connecting to expressjs app from angularjs

I am trying to build an application with angularjs as front end and rest api using express js. I built both the projects using yeoman and my angular app is running on localhost:9000 and my express app is running on localhost:3000. When i try to talk to express js app from angular, I am getting a cross domain request, is there any way to fix this.
app.js in Express App
var routes = require('./routes/signup')(app); //This is the extra line
app.all('*', function(req, res, next) {
res.header("Access-Control-Allow-Origin", "{GRUNT_SERVER}");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
res.header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
res.header("Access-Control-Allow-Credentials", "true");
next();
});
app.get('/', function(req, res) {
res.json({ message: 'hooray! welcome to our api!' });
});
app.js in angularjs app
$httpProvider.defaults.useXDomain = true;
delete $httpProvider.defaults.headers.common['X-Requested-With'];
$httpProvider.defaults.withCredentials = true;
Error
No 'Access-Control-Allow-Origin' header is present on the requested resource.
Origin 'http://localhost:9000' is therefore not allowed access.
The response had HTTP status code 409.
EDIT
Here's the code that I added to my app.js file:
// allow CORS:
app.use(function (req, res, next) {
res.setHeader('Access-Control-Allow-Origin', 'http://localhost:8000');
next();
});
This also throws the same error ("No 'Access-Control-Allow-Origin' header is present on the requested resource.") as before.
EDIT
After using
var express = require('express')
, cors = require('cors')
, app = express();
app.use(cors());
This is throwing POST localhost:3000/signup 409 (Conflict)
Use npm cors - https://github.com/expressjs/cors to allow cors request.
var express = require('express')
, cors = require('cors')
, app = express();
app.use(cors());
app.get('/', function(req, res) {
res.json({ message: 'hooray! welcome to our api!' });
});
app.listen(3000);

Resources