Nodejs Express CORS issue with 'Access-Control-Allow-Origin'
Solution 1
While the answer by @muratgozel is partially correct , let me go a little deeper on CORS and why the issue is caused . When your browser sends a cross-origin response , it gives it's Origin in the header . The server response also gives a header called Access-Control-Allow-Origin. When you use instantiate the 'cors' module in your express app , the Access-Control-Allow-Origin header is set to be '*' a wildcard , which basically means it this server resource (of the express app) is public and can be accessed from any code anywhere, However the limitation of this wildcard is that certain request headers such as Authorization are not allowed in the request. Your request from the index.html page has it's set of headers . Either you should look into the headers or you can simply do what @muratgozel said and instantiate cors with a specific origin Except just set the credentials option to true
app.use(cors({ origin: 'http://example.com' , credentials : true}));
Solution 2
There is also an option to set origin
to true
to reflect the request origin, as defined by req.header('Origin')
.
app.use(cors({ origin: true, credentials: true }));
Solution 3
Your cors
package has an origin option which changes the "Access-Control-Allow-Origin" header.
Specify origin option where you initiate cors() function:
app.use(cors({ origin: 'http://example.com' }));
Also there are more details at the cors package npm page
fambo
Updated on July 02, 2022Comments
-
fambo almost 2 years
I'm trying to create a single page app using Angular 1, Nodejs and Express. I'm using Angular's $http post feature to post a request where I pass header values in the request to an API endpoint.
I am encountering an error message in Chrome:
XMLHttpRequest cannot load http://localhost:7878/EIAMIDSupportREST/EIAMIDSupport/updateEIAMID. 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.
With this request body:
HTTP/1.1 200 OK X-Powered-By: Express Access-Control-Allow-Origin: * Access-Control-Allow-Methods: GET,PUT,POST,PATCH,DELETE Access-Control-Allow-Headers: Content-Type Allow: POST Content-Type: text/html; charset=utf-8 Content-Length: 4 Date: Tue, 23 May 2017 23:32:15 GMT Connection: keep-alive
To remedy the CORS issue, I've npm installed the
cors
library.In my app.js, I have the add the following lines:
var cors = require('cors'); var app = express(); app.use(cors());
Here is my full app.js:
var express = require('express'); var path = require('path'); var favicon = require('serve-favicon'); var logger = require('morgan'); var cookieParser = require('cookie-parser'); var bodyParser = require('body-parser'); var index = require('./routes/index'); var users = require('./routes/users'); var cons = require('consolidate'); //enable CORS var cors = require('cors'); var app = express(); app.use(cors({ origin: 'http://localhost:3000' , credentials : true, methods: 'GET,PUT,POST,OPTIONS', allowedHeaders: 'Content-Type,Authorization' })); // view engine setup app.engine('html', cons.swig) app.set('views', path.join(__dirname, 'views')); app.set('view engine', 'html'); // uncomment after placing your favicon in /public //app.use(favicon(path.join(__dirname, 'public', 'favicon.ico'))); app.use(logger('dev')); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: false })); app.use(cookieParser()); app.use(express.static(path.join(__dirname, 'public'))); app.use('/', index); app.use('/users', users); // catch 404 and forward to error handler app.use(function(req, res, next) { var err = new Error('Not Found'); err.status = 404; next(err); }); // error handler app.use(function(err, req, res, next) { // set locals, only providing error in development res.locals.message = err.message; res.locals.error = req.app.get('env') === 'development' ? err : {}; // render the error page res.status(err.status || 500); res.render('error'); }); module.exports = app;
And here is my index.html page
<html> <head> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script> <script type="text/javascript"> var app = angular.module("app", []); app.controller("HttpGetController", function ($scope, $http) { $scope.SendData = function () { var req = { method: 'POST', url: 'http://localhost:7878/EIAMIDSupportREST/EIAMIDSupport/updateEIAMID', withCredentials: true, headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'Authorization': 'Basic user:password' } } $http(req) .then(function(data, status, header, config) { $scope.PostDataResponse = data, console.log($scope.PostDataResponse); }) .catch(function(data, status, header, config) { $scope.PostDataResponse = data, console.log($scope.PostDataResponse); }); }; }); </script> </head> <body> <div ng-app="app"> <div ng-controller="HttpGetController"> <button ng-click="SendData()" >Link Accounts</button> <hr />AND THE RESPONSE IS:{{ PostDataResponse }} </div> </div> </body> </html>
However, it still does not work.
Can anyone please advise how and where I need to update my code to fix the 'Access-Control-Allow-Origin' wildcard issue?
-
fambo almost 7 yearsI tried you suggestion and updated the app.js with app.use(cors({ origin: 'localhost:3000' , credentials : true, methods: 'GET,PUT,POST,OPTIONS', allowedHeaders: 'Content-Type,Authorization' })); however, in the chrome inspector it appears that my changes are not in effect. What am I missing ? please help :)
-
therebelcoder almost 7 yearsRead the answer above and it seems sound. Can you add an edit to the original question with the exact error messages you're getting? And maybe node.js code too? The more info the better.
-
rajesh-nitc about 5 yearsbest answer on cors issue
-
Oleksandr Oliynyk about 5 yearsSaved my day! Nowhere saw this
credentials : true
option mentioned and explanation is good. Thanks!