By user1336103


2013-08-19 09:22:50 8 Comments

i've created a small API using Node/Express and trying to pull data using Angularjs but as my html page is running under apache on localhost:8888 and node API is listen on port 3000, i am getting the No 'Access-Control-Allow-Origin'. I tried using node-http-proxy and Vhosts Apache but not having much succes, please see full error and code below.

"XMLHttpRequest cannot load localhost:3000. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'localhost:8888' is therefore not allowed access."

// Api Using Node/Express    
var express = require('express');
var app = express();
var contractors = [
    {   
     "id": "1", 
        "name": "Joe Blogg",
        "Weeks": 3,
        "Photo": "1.png"
    }
];

app.use(express.bodyParser());

app.get('/', function(req, res) {
  res.json(contractors);
});
app.listen(process.env.PORT || 3000);
console.log('Server is running on Port 3000')


    // Angular code
    angular.module('contractorsApp', [])
    .controller('ContractorsCtrl', function($scope, $http,$routeParams) {

   $http.get('localhost:3000').success(function(data) {

    $scope.contractors = data;

   })

   // HTML
   <body ng-app="contractorsApp">
    <div ng-controller="ContractorsCtrl"> 
        <ul>
         <li ng-repeat="person in contractors">{{person.name}}</li>
        </ul>
    </div>
   </body>

12 comments

@Karthik S Kumar 2019-08-18 14:01:06

Hi this happens when the front end and backend is running on different ports. The browser blocks the responses from the backend due to the absence on CORS headers. The solution is to make add the CORS headers in the backend request. The easiest way is to use cors npm package.

var express = require('express')
var cors = require('cors')
var app = express()
app.use(cors())

This will enable CORS headers in all your request. For more information you can refer to cors documentation

https://www.npmjs.com/package/cors

@dmx 2018-12-15 11:31:11

This worked for me.

app.get('/', function (req, res) {

    res.header("Access-Control-Allow-Origin", "*");
    res.send('hello world')
})

You can change * to fit your needs. Hope this can help.

@monikaja 2018-08-29 09:21:21

Install cors dependency in your project:

npm i --save cors

Add to your server configuration file the following:

var cors = require('cors');
app.use(cors());

It works for me with 2.8.4 cors version.

@RamiroIsBack 2018-11-27 20:05:31

"cors": "^2.8.5", "express": "^4.16.3", works fine just with the line @monikaja suggested. Thanks!

@Lacho Tomov 2019-07-05 11:25:09

What this does is to enable all origins/domains to access the app which is something you usually don't want to do. Instead specify just the allowed domains.

@Ezhil Arasan 2018-05-22 14:55:20

//Add following code in app.js of NODEJ Restful api to avoid "Access-Control-Allow-Origin" error in angular 6 or any other framework

var express = require('express');
var app = express();

var cors = require('cors');
var bodyParser = require('body-parser');

//enables cors
app.use(cors({
  'allowedHeaders': ['sessionId', 'Content-Type'],
  'exposedHeaders': ['sessionId'],
  'origin': '*',
  'methods': 'GET,HEAD,PUT,PATCH,POST,DELETE',
  'preflightContinue': false
}));

@Asaf Hananel 2016-11-26 16:14:06

Another way, is simply add the headers to your route:

router.get('/', function(req, res) {
    res.setHeader('Access-Control-Allow-Origin', '*');
    res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE'); // If needed
    res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type'); // If needed
    res.setHeader('Access-Control-Allow-Credentials', true); // If needed

    res.send('cors problem fixed:)');
});

@diEcho 2017-05-20 11:41:39

) of smiley confused me

@Dan Abramov 2014-03-28 17:30:08

The top answer worked fine for me, except that I needed to whitelist more than one domain.

Also, top answer suffers from the fact that OPTIONS request isn't handled by middleware and you don't get it automatically.

I store whitelisted domains as allowed_origins in Express configuration and put the correct domain according to origin header since Access-Control-Allow-Origin doesn't allow specifying more than one domain.

Here's what I ended up with:

var _ = require('underscore');

function allowCrossDomain(req, res, next) {
  res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');

  var origin = req.headers.origin;
  if (_.contains(app.get('allowed_origins'), origin)) {
    res.setHeader('Access-Control-Allow-Origin', origin);
  }

  if (req.method === 'OPTIONS') {
    res.send(200);
  } else {
    next();
  }
}

app.configure(function () {
  app.use(express.logger());
  app.use(express.bodyParser());
  app.use(allowCrossDomain);
});

@Rune Jeppesen 2016-12-13 21:15:58

Is this the same 'if (app.get('allowed origins').indexOf(origin)!==-1)?'?

@Vicheanak 2016-07-06 17:31:24

The answer code allow only to localhost:8888. This code can't be deployed to the production, or different server and port name.

To get it working for all sources, use this instead:

// Add headers
app.use(function (req, res, next) {

    // Website you wish to allow to connect
    res.setHeader('Access-Control-Allow-Origin', '*');

    // Request methods you wish to allow
    res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');

    // Request headers you wish to allow
    res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');

    // Set to true if you need the website to include cookies in the requests sent
    // to the API (e.g. in case you use sessions)
    res.setHeader('Access-Control-Allow-Credentials', true);

    // Pass to next layer of middleware
    next();
});

@Francesco 2016-09-29 10:19:58

This does not work for me! " * is not a valid origin ". It seems the * character is not recognized as a wildcard.

@Annjawn 2017-04-25 08:38:22

It works for me. i.e. using wild card '*'. works both for chrome and safari.

@Mauro 2018-10-08 09:37:20

Thanks ;) Works fine

@Luton Datta 2016-07-02 06:18:33

/**
 * Allow cross origin to access our /public directory from any site.
 * Make sure this header option is defined before defining of static path to /public directory
 */
expressApp.use('/public',function(req, res, next) {
    res.setHeader("Access-Control-Allow-Origin", "*");
    // Request headers you wish to allow
    res.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
    // Set to true if you need the website to include cookies in the requests sent
    res.setHeader('Access-Control-Allow-Credentials', true);
    // Pass to next layer of middleware
    next();
});


/**
 * Server is about set up. Now track for css/js/images request from the 
 * browser directly. Send static resources from "./public" directory. 
 */
expressApp.use('/public', express.static(path.join(__dirname, 'public')));
If you want to set Access-Control-Allow-Origin to a specific static directory you can set the following.

@Wiki 2015-12-21 12:51:03

app.all('*', function(req, res,next) {
    /**
     * Response settings
     * @type {Object}
     */
    var responseSettings = {
        "AccessControlAllowOrigin": req.headers.origin,
        "AccessControlAllowHeaders": "Content-Type,X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5,  Date, X-Api-Version, X-File-Name",
        "AccessControlAllowMethods": "POST, GET, PUT, DELETE, OPTIONS",
        "AccessControlAllowCredentials": true
    };

    /**
     * Headers
     */
    res.header("Access-Control-Allow-Credentials", responseSettings.AccessControlAllowCredentials);
    res.header("Access-Control-Allow-Origin",  responseSettings.AccessControlAllowOrigin);
    res.header("Access-Control-Allow-Headers", (req.headers['access-control-request-headers']) ? req.headers['access-control-request-headers'] : "x-requested-with");
    res.header("Access-Control-Allow-Methods", (req.headers['access-control-request-method']) ? req.headers['access-control-request-method'] : responseSettings.AccessControlAllowMethods);

    if ('OPTIONS' == req.method) {
        res.send(200);
    }
    else {
        next();
    }


});

@Grant 2019-06-28 00:51:10

This worked perfect, thanks

@Fabiano Soriani 2015-12-18 00:11:24

Accepted answer is fine, in case you prefer something shorter, you may use a plugin called cors available for Express.js

It's simple to use, for this particular case:

var cors = require('cors');

// use it before all route definitions
app.use(cors({origin: 'http://localhost:8888'}));

@Ricardo Cruz 2016-07-03 11:17:27

I had to use {origin: 'null'} for it to work... Apparently, my browser sends null as the origin?

@Pierre 2017-01-04 20:14:19

Why reinvent the wheel. I am always for a packaged solution compared to code snippet

@Kyle Baker 2017-02-15 19:41:37

sweet little library that handled my use case of wanting different methods from different origins quite nicely... and less code fatigue for the next guy looking at it.

@danialk 2017-08-26 17:02:50

Thanks, app.use(cors({origin: '*'})); worked for me, as per enable-cors.

@13013SwagR 2019-03-17 17:53:00

I suggest having a look at the npm cors page to make better use of it. It made things very clear for me =).

@JQuery Guru 2013-08-19 09:30:31

You can use "$http.jsonp"

OR

Below is the work around for chrome for local testing

You need to open your chrome with following command. (Press window+R)

Chrome.exe --allow-file-access-from-files

Note : Your chrome must not be open. When you run this command chrome will open automatically.

If you are entering this command in command prompt then select your chrome installation directory then use this command.

Below script code for open chrome in MAC with "--allow-file-access-from-files"

set chromePath to POSIX path of "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" 
set switch to " --allow-file-access-from-files"
do shell script (quoted form of chromePath) & switch & " > /dev/null 2>&1 &"

second options

You can just use open(1) to add the flags: open -a 'Google Chrome' --args --allow-file-access-from-files

@user1336103 2013-08-19 09:38:44

How about on MAC ?? Chrome.exe --allow-file-access-from-files

@user1336103 2013-08-19 09:46:06

/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --allow-file-access-from-files manage to open chrome but the message is still showing "XMLHttpRequest cannot load localhost:3000. Origin localhost:8888 is not allowed by Access-Control-Allow-Origin. "

@JQuery Guru 2013-08-20 10:48:24

@user1336103 Added code for MAC check if it works for you

@spong 2013-09-05 03:17:10

+1 I can confirm this works with the Mac option using 'open'. My case is a little different as I'm simply testing a completely downloaded site that accesses some local JSON files.

@jvandemo 2013-08-19 10:23:25

Try adding the following middleware to your NodeJS/Express app (I have added some comments for your convenience):

// Add headers
app.use(function (req, res, next) {

    // Website you wish to allow to connect
    res.setHeader('Access-Control-Allow-Origin', 'http://localhost:8888');

    // Request methods you wish to allow
    res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');

    // Request headers you wish to allow
    res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');

    // Set to true if you need the website to include cookies in the requests sent
    // to the API (e.g. in case you use sessions)
    res.setHeader('Access-Control-Allow-Credentials', true);

    // Pass to next layer of middleware
    next();
});

Hope that helps!

@Art Geigel 2013-10-14 22:06:45

Can you help specify exactly where that goes? I have the following code in my server. Does it go right after this? var app = require('express')() , server = require('http').createServer(app) , io = require('socket.io').listen(server) , request = require("request") , url = require("url"); server.listen(6969); // does it go here? on a new line?

@jvandemo 2013-10-19 13:37:30

It is a middleware function. You can put it after the require lines and before the server.listen line. Hope that helps!

@Sangram Singh 2013-12-01 03:47:36

@jvandemo do i have to change the app.get('/', function(req, res) to ...function(req, res, next) ?

@jvandemo 2013-12-25 05:42:37

@SangramSingh Yes, the next argument is optional but you need to specify it in case you use it inside your function.

@gegillam 2016-02-04 03:01:49

You are my favorite person ever right now. Thank you. Can we add a note that this code has to happen before the routes are defined for noobs like me?

@Gurpinder 2016-04-27 09:16:21

What if i am using 3rd Party API ? I can't add "Allow Access" on their server. You are showing example of local project. I am having same issue but with my request is goes to another website url. How to fix it any idea ?

@Mahesh 2016-10-04 15:51:35

@Gurpinder - CORS was created to prevent client from unauthorized access. If you want to have access, you need the 3rd party app owner to add you to his authorized users. Else I can simply create my own MyGoogle website, provide search query, and present the results as my own.

@Mahesh 2016-10-04 15:59:33

@gegillam -> Thanks for your comment. I was adding this line after the routes were defined. :/ It works fine after putting the above code, just after creating the app object.

@Rohit Tigga 2016-11-26 23:04:32

How to make this work while using the request module?

@Paul Fitzgerald 2016-12-02 17:07:37

@RohitTigga did you ever find how to get this working with request?

@Pedro Emilio Borrego Rached 2017-01-13 20:18:22

Wow buddy this is the ultimate hat trick, thanks man, I would never guess this solution.

@user1451111 2018-02-13 11:47:53

It did not work in my case. Still getting this error: "Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'abc.xyz.net:212' is therefore not allowed access. The response had HTTP status code 500."

@Johan Hoeksma 2018-07-18 08:03:39

perfect, for testing I replaced 'localhost:8888' with '*' not safe, but great for testing

@Kubie 2019-07-02 14:41:53

@JohanHoeksma is there a reason why that isn't so safe? How did you setup for production?

@Johan Hoeksma 2019-07-02 15:37:33

So any origin can connect now. For a localhost it's not a problem. On a server I think you don't want it...

Related Questions

Sponsored Content

11 Answered Questions

[SOLVED] Access-Control-Allow-Origin wildcard subdomains, ports and protocols

  • 2012-12-22 13:44:26
  • Elie
  • 280872 View
  • 273 Score
  • 11 Answer
  • Tags:   cors

17 Answered Questions

29 Answered Questions

[SOLVED] Access-Control-Allow-Origin Multiple Origin Domains?

13 Answered Questions

[SOLVED] How does Access-Control-Allow-Origin header work?

2 Answered Questions

1 Answered Questions

1 Answered Questions

[SOLVED] how to work around a Access-Control-Allow-Origin error

2 Answered Questions

[SOLVED] No 'Access-Control-Allow-Origin' header issue with hapijs

Sponsored Content