[node.js] No 'Access-Control-Allow-Origin' - Node / Apache Port Issue

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>

This question is related to node.js angularjs rest express cors

The answer is


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.


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


});

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

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

All the other answers didn't work for me. (including cors package, or setting headers through middleware)

For socket.io 3^ this worked without any extra packages.

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

const server = require('http').createServer(app);
const io = require('socket.io')(server, {
    cors: {
        origin: "*",
        methods: ["GET", "POST"]
    }
});

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

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

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


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

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


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.


_x000D_
_x000D_
/**_x000D_
 * Allow cross origin to access our /public directory from any site._x000D_
 * Make sure this header option is defined before defining of static path to /public directory_x000D_
 */_x000D_
expressApp.use('/public',function(req, res, next) {_x000D_
    res.setHeader("Access-Control-Allow-Origin", "*");_x000D_
    // Request headers you wish to allow_x000D_
    res.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");_x000D_
    // Set to true if you need the website to include cookies in the requests sent_x000D_
    res.setHeader('Access-Control-Allow-Credentials', true);_x000D_
    // Pass to next layer of middleware_x000D_
    next();_x000D_
});_x000D_
_x000D_
_x000D_
/**_x000D_
 * Server is about set up. Now track for css/js/images request from the _x000D_
 * browser directly. Send static resources from "./public" directory. _x000D_
 */_x000D_
expressApp.use('/public', express.static(path.join(__dirname, 'public')));
_x000D_
If you want to set Access-Control-Allow-Origin to a specific static directory you can set the following.
_x000D_
_x000D_
_x000D_


Apart from all listed answers, I had the same error

I have both access to frontend and backend, I already added cors module app.use(cors()); Still, I was struggling with this error.

After some debugging, I found the issue. When I upload a media which size was more than 1 MB then the error was thrown by Nginx server

<html>

<head>
    <title>413 Request Entity Too Large</title>
</head>

<body>
    <center>
        <h1>413 Request Entity Too Large</h1>
    </center>
    <hr>
    <center>nginx/1.18.0</center>
</body>

</html>

But in the console of frontend, I found the error

Access to XMLHttpRequest at 'https://api.yourbackend.com' from origin 'https://web.yourfromntend.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

So It makes confusion here. But the route cause of this error was from nginx configuration. It's just because the directive client_max_body_size value has been set to 0 by default. It determines what the allowable HTTP request size can be is client_max_body_size. This directive may already be defined in your nginx.conf file located at /etc/nginx/nginx.conf Now you need to add/edit the value of the directive client_max_body_size either at http or server.

server {
    client_max_body_size 100M;
    ...
}

Once you have set your desired value, save your changes and reload Nginx: service nginx reload

After these changes, It's working well

REFERENCE: https://www.keycdn.com/support/413-request-entity-too-large#:~:text=%23,processed%20by%20the%20web%20server.&text=An%20example%20request%2C%20that%20may,e.g.%20a%20large%20media%20file).


Examples related to node.js

Hide Signs that Meteor.js was Used Querying date field in MongoDB with Mongoose SyntaxError: Cannot use import statement outside a module Server Discovery And Monitoring engine is deprecated How to fix ReferenceError: primordials is not defined in node UnhandledPromiseRejectionWarning: This error originated either by throwing inside of an async function without a catch block dyld: Library not loaded: /usr/local/opt/icu4c/lib/libicui18n.62.dylib error running php after installing node with brew on Mac internal/modules/cjs/loader.js:582 throw err DeprecationWarning: Buffer() is deprecated due to security and usability issues when I move my script to another server Please run `npm cache clean`

Examples related to angularjs

AngularJs directive not updating another directive's scope ERROR in Cannot find module 'node-sass' CORS: credentials mode is 'include' CORS error :Request header field Authorization is not allowed by Access-Control-Allow-Headers in preflight response WebSocket connection failed: Error during WebSocket handshake: Unexpected response code: 400 Print Html template in Angular 2 (ng-print in Angular 2) $http.get(...).success is not a function Angular 1.6.0: "Possibly unhandled rejection" error Find object by its property in array of objects with AngularJS way Error: Cannot invoke an expression whose type lacks a call signature

Examples related to rest

Access blocked by CORS policy: Response to preflight request doesn't pass access control check Returning data from Axios API Access Control Origin Header error using Axios in React Web throwing error in Chrome JSON parse error: Can not construct instance of java.time.LocalDate: no String-argument constructor/factory method to deserialize from String value How to send json data in POST request using C# How to enable CORS in ASP.net Core WebAPI RestClientException: Could not extract response. no suitable HttpMessageConverter found REST API - Use the "Accept: application/json" HTTP Header 'Field required a bean of type that could not be found.' error spring restful API using mongodb MultipartException: Current request is not a multipart request

Examples related to express

UnhandledPromiseRejectionWarning: This error originated either by throwing inside of an async function without a catch block jwt check if token expired Avoid "current URL string parser is deprecated" warning by setting useNewUrlParser to true MongoNetworkError: failed to connect to server [localhost:27017] on first connect [MongoNetworkError: connect ECONNREFUSED 127.0.0.1:27017] npm notice created a lockfile as package-lock.json. You should commit this file Make Axios send cookies in its requests automatically What does body-parser do with express? SyntaxError: Unexpected token function - Async Await Nodejs Route.get() requires callback functions but got a "object Undefined" How to redirect to another page in node.js

Examples related to cors

Axios having CORS issue Cross-Origin Read Blocking (CORB) Jquery AJAX: No 'Access-Control-Allow-Origin' header is present on the requested resource How to allow CORS in react.js? Set cookies for cross origin requests XMLHttpRequest blocked by CORS Policy How to enable CORS in ASP.net Core WebAPI No 'Access-Control-Allow-Origin' header is present on the requested resource—when trying to get data from a REST API How to overcome the CORS issue in ReactJS Trying to use fetch and pass in mode: no-cors