No 'Access-Control-Allow-Origin' - Node / Apache Port Issue

441,244

Solution 1

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

// Add headers before the routes are defined
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!

Solution 2

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'}));

Solution 3

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:)');
});

Solution 4

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);
});

Solution 5

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.

Share:
441,244
user1336103
Author by

user1336103

Updated on July 08, 2022

Comments

  • user1336103
    user1336103 almost 2 years

    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').then(function(response) {
           var data = response.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>
    
  • user1336103
    user1336103 over 10 years
    How about on MAC ?? Chrome.exe --allow-file-access-from-files
  • user1336103
    user1336103 over 10 years
    /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. "
  • spong
    spong over 10 years
    +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.
  • Art Geigel
    Art Geigel over 10 years
    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
    jvandemo over 10 years
    It is a middleware function. You can put it after the require lines and before the server.listen line. Hope that helps!
  • Sangram Singh
    Sangram Singh over 10 years
    @jvandemo do i have to change the app.get('/', function(req, res) to ...function(req, res, next) ?
  • jvandemo
    jvandemo over 10 years
    @SangramSingh Yes, the next argument is optional but you need to specify it in case you use it inside your function.
  • gegillam
    gegillam over 8 years
    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
    Gurpinder about 8 years
    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 ?
  • Ricardo Magalhães Cruz
    Ricardo Magalhães Cruz almost 8 years
    I had to use {origin: 'null'} for it to work... Apparently, my browser sends null as the origin?
  • Francesco
    Francesco over 7 years
    This does not work for me! " * is not a valid origin ". It seems the * character is not recognized as a wildcard.
  • Mahesh
    Mahesh over 7 years
    @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
    Mahesh over 7 years
    @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
    Rohit Tigga over 7 years
    How to make this work while using the request module?
  • Paul Fitzgerald
    Paul Fitzgerald over 7 years
    @RohitTigga did you ever find how to get this working with request?
  • Rune Jeppesen
    Rune Jeppesen over 7 years
    Is this the same 'if (app.get('allowed origins').indexOf(origin)!==-1)?'?
  • Pierre
    Pierre over 7 years
    Why reinvent the wheel. I am always for a packaged solution compared to code snippet
  • Pedro Emilio Borrego Rached
    Pedro Emilio Borrego Rached over 7 years
    Wow buddy this is the ultimate hat trick, thanks man, I would never guess this solution.
  • Kyle Baker
    Kyle Baker over 7 years
    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.
  • AnBisw
    AnBisw about 7 years
    It works for me. i.e. using wild card '*'. works both for chrome and safari.
  • Anton
    Anton almost 7 years
    ) of smiley confused me
  • danialk
    danialk over 6 years
    Thanks, app.use(cors({origin: '*'})); worked for me, as per enable-cors.
  • user1451111
    user1451111 over 6 years
    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
    Johan Hoeksma almost 6 years
    perfect, for testing I replaced 'localhost:8888' with '*' not safe, but great for testing
  • Mauro
    Mauro over 5 years
    Thanks ;) Works fine
  • RamiroIsBack
    RamiroIsBack over 5 years
    "cors": "^2.8.5", "express": "^4.16.3", works fine just with the line @monikaja suggested. Thanks!
  • 13013SwagR
    13013SwagR about 5 years
    I suggest having a look at the npm cors page to make better use of it. It made things very clear for me =).
  • Kubie
    Kubie almost 5 years
    @JohanHoeksma is there a reason why that isn't so safe? How did you setup for production?
  • Johan Hoeksma
    Johan Hoeksma almost 5 years
    So any origin can connect now. For a localhost it's not a problem. On a server I think you don't want it...
  • LachoTomov
    LachoTomov almost 5 years
    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.
  • Cowthulhu
    Cowthulhu over 4 years
    Thank you - I was tearing my hair out trying to get this working. Worth noting that the website is case sensitive.
  • Program-Me-Rev
    Program-Me-Rev about 4 years
    I wish I bumped into this 4 hours ago!
  • Yuyutsu
    Yuyutsu almost 4 years
    How to fix this in hapiJS
  • Yuyutsu
    Yuyutsu almost 4 years
    How to fixed this in HapiJS
  • ultrageek
    ultrageek almost 4 years
    After 4-5 hours of searching, this is the only solution that actually works for me. Thanks
  • Nijat Mursali
    Nijat Mursali over 3 years
    This is a best reply ever! Worked with socketio. Thanks
  • Soth
    Soth almost 3 years
    I ran into this problem with a POST request but it had to do with the upload size being too large. It was a very misleading error.
  • RegarBoy
    RegarBoy over 2 years
    Isn't this approach much simpler? stackoverflow.com/a/40820322/5035986
  • Rushikesh Shelke
    Rushikesh Shelke over 2 years
    How do we allow for all origins instead of just localhost:8888 ? Is adding an asterisk instead of url like res.setHeader('Access-Control-Allow-Origin', '*'); a valid way ?