I have a problem when trying to communicate with my node.js server from ajax requests.
I have configured my server like this :
var allowCrossDomain = 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.use(allowCrossDomain);When doing my requests I have this error :
XMLHttpRequest cannot load //10.192.122.180:8181/meters. No 'Access-Control-Allow- Origin' header is present on the requested resource. Origin '//localhost:6161' is therefore not allowed access.Could someone help me please ?
Thanks!
I have an API running on a server and a front-end client connecting to it to retrieve data. I did some research on the cross domain problem and has it working. However I've not sure what has changed. I am now getting this error in the console:
XMLHttpRequest cannot load //api.mydomain/api/status. No
'Access-Control-Allow-Origin' header is present on the requested
resource. Origin '//beta.mydomain.com' is therefore not allowed
access. The response had HTTP status code 502.
I have the following route file:
var express = require('express'); var router = express.Router(); var Assessment = require('../app/models/assessment'); router.all('*', function (req, res, next) { res.header('Access-Control-Allow-Origin', '*'); res.header('Access-Control-Allow-Methods', 'PUT, GET, POST, DELETE, OPTIONS'); res.header('Access-Control-Allow-Headers', 'Content-Type'); next(); }); router.post('/api/status', function (req, res, next) { getStatus.getStatus(req, res, Assessment); }); module.exports = router;And the following JavaScript making an Ajax call to that route:
I have tried:
Putting the requesting domain in the 'Access-Control-Allow-Origin' header
Using the cors module for express
Putting my router.all function inside
middleware
The requesting domain is HTTP and the api domain is on HTTPS. However, I have had it working while the HTTP was enabled.
Does anyone have any insight into why the 'Access-Control-Allow-Origin' header is not being send?
Thank you
I have an API running on a server and a front-end client connecting to it to retrieve data. I did some research on the cross domain problem and has it working. However I've not sure what has changed. I am now getting this error in the console:
XMLHttpRequest cannot load //api.mydomain/api/status. No
'Access-Control-Allow-Origin' header is present on the requested
resource. Origin '//beta.mydomain.com' is therefore not allowed
access. The response had HTTP status code 502.
I have the following route file:
var express = require('express');
var router = express.Router();
var Assessment = require('../app/models/assessment');
router.all('*', function (req, res, next) {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'PUT, GET, POST, DELETE, OPTIONS');
res.header('Access-Control-Allow-Headers', 'Content-Type');
next();
});
router.post('/api/status', function (req, res, next) {
getStatus.getStatus(req, res, Assessment);
});
module.exports = router;
And the following JavaScript making an Ajax call to that route:
var user = {
'uid' : '12345'
};
$.ajax({
data: user,
method: 'POST',
url: '//api.mydomain/api/status',
crossDomain: true,
done: function () {
},
success: function (data) {
console.log(JSON.stringify(data));
},
error: function (xhr, status) {
}
});
I have tried:
Putting the requesting domain in the 'Access-Control-Allow-Origin' header
Using the cors module for express
Putting my router.all
function inside middleware
The requesting domain is HTTP and the api domain is on HTTPS. However, I have had it working while the HTTP was enabled.
Does anyone have any insight into why the 'Access-Control-Allow-Origin' header is not being send?
Thank you
CORS is a node.js package for providing a Connect/Express middleware that can be used to enable CORS with various options.
Follow me (@troygoode) on Twitter!
- Installation
- Usage
- Simple Usage
- Enable CORS for a Single Route
- Configuring CORS
- Configuring CORS w/ Dynamic Origin
- Enabling CORS Pre-Flight
- Configuring CORS Asynchronously
- Configuration Options
- Demo
- License
- Author
Installation
This is a Node.js module available through the npm registry. Installation is done using the npm install command:
$ npm install corsUsage
Simple Usage (Enable All CORS Requests)
var express = require('express') var cors = require('cors') var app = express() app.use(cors()) app.get('/products/:id', function (req, res, next) { res.json({msg: 'This is CORS-enabled for all origins!'}) }) app.listen(80, function () { console.log('CORS-enabled web server listening on port 80') })Enable CORS for a Single Route
var express = require('express') var cors = require('cors') var app = express() app.get('/products/:id', cors(), function (req, res, next) { res.json({msg: 'This is CORS-enabled for a Single Route'}) }) app.listen(80, function () { console.log('CORS-enabled web server listening on port 80') })Configuring CORS
var express = require('express') var cors = require('cors') var app = express() var corsOptions = { origin: '//example.com', optionsSuccessStatus: 200 // some legacy browsers (IE11, various SmartTVs) choke on 204 } app.get('/products/:id', cors(corsOptions), function (req, res, next) { res.json({msg: 'This is CORS-enabled for only example.com.'}) }) app.listen(80, function () { console.log('CORS-enabled web server listening on port 80') })Configuring CORS w/ Dynamic Origin
This module supports validating the origin dynamically using a function provided to the origin option. This function will be passed a string that is the origin (or undefined if the request has no origin), and a callback with the signature callback(error, origin).
The origin argument to the callback can be any value allowed for the origin option of the middleware, except a function. See the configuration options section for more information on all the possible value types.
This function is designed to allow the dynamic loading of allowed origin(s) from a backing datasource, like a database.
var express = require('express') var cors = require('cors') var app = express() var corsOptions = { origin: function (origin, callback) { // db.loadOrigins is an example call to load // a list of origins from a backing database db.loadOrigins(function (error, origins) { callback(error, origins) }) } } app.get('/products/:id', cors(corsOptions), function (req, res, next) { res.json({msg: 'This is CORS-enabled for an allowed domain.'}) }) app.listen(80, function () { console.log('CORS-enabled web server listening on port 80') })Enabling CORS Pre-Flight
Certain CORS requests are considered ‘complex’ and require an initial OPTIONS request (called the “pre-flight request”). An example of a ‘complex’ CORS request is one that uses an HTTP verb other than GET/HEAD/POST (such as DELETE) or that uses custom headers. To enable pre-flighting, you must add a new OPTIONS handler for the route you want to support:
var express = require('express') var cors = require('cors') var app = express() 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!'}) }) app.listen(80, function () { console.log('CORS-enabled web server listening on port 80') })You can also enable pre-flight across-the-board like so:
app.options('*', cors()) // include before other routesNOTE: When using this middleware as an application level middleware (for example, app.use(cors())), pre-flight requests are already handled for all routes.
Configuring CORS Asynchronously
var express = require('express') var cors = require('cors') var app = express() var allowlist = ['//example1.com', '//example2.com'] var corsOptionsDelegate = function (req, callback) { var corsOptions; if (allowlist.indexOf(req.header('Origin')) !== -1) { corsOptions = { origin: true } // reflect (enable) the requested origin in the CORS response } else { corsOptions = { origin: false } // disable CORS for this request } callback(null, corsOptions) // callback expects two parameters: error and options } app.get('/products/:id', cors(corsOptionsDelegate), function (req, res, next) { res.json({msg: 'This is CORS-enabled for an allowed domain.'}) }) app.listen(80, function () { console.log('CORS-enabled web server listening on port 80') })Configuration Options
- origin: Configures the Access-Control-Allow-Origin CORS header. Possible values:
- Boolean - set origin to true to reflect the request origin, as defined by req.header('Origin'), or set it to false to disable CORS.
- String - set origin to a specific origin. For example if you set it to "//example.com" only requests from “//example.com” will be allowed.
- RegExp - set origin to a regular expression pattern which will be used to test the request origin. If it’s a match, the request origin will be reflected. For example the pattern /example\.com$/ will reflect any request that is coming from an origin ending with “example.com”.
- Array - set origin to an array of valid origins. Each origin can be a String or a RegExp. For example ["//example1.com", /\.example2\.com$/] will accept any request from “//example1.com” or from a subdomain of “example2.com”.
- Function - set origin to a function implementing some custom logic. The function takes the request origin as the first parameter and a callback (called as callback(err, origin), where origin is a non-function value of the origin option) as the second.
- methods: Configures the Access-Control-Allow-Methods CORS header. Expects a comma-delimited string (ex: ‘GET,PUT,POST’) or an array (ex: ['GET', 'PUT', 'POST']).
- allowedHeaders: Configures the Access-Control-Allow-Headers CORS header. Expects a comma-delimited string (ex: ‘Content-Type,Authorization’) or an array (ex: ['Content-Type', 'Authorization']). If not specified, defaults to reflecting the headers specified in the request’s Access-Control-Request-Headers header.
- exposedHeaders: Configures the Access-Control-Expose-Headers CORS header. Expects a comma-delimited string (ex: ‘Content-Range,X-Content-Range’) or an array (ex: ['Content-Range', 'X-Content-Range']). If not specified, no custom headers are exposed.
- credentials: Configures the Access-Control-Allow-Credentials CORS header. Set to true to pass the header, otherwise it is omitted.
- maxAge: Configures the Access-Control-Max-Age CORS header. Set to an integer to pass the header, otherwise it is omitted.
- preflightContinue: Pass the CORS preflight response to the next handler.
- optionsSuccessStatus: Provides a status code to use for successful OPTIONS requests, since some legacy browsers (IE11, various SmartTVs) choke on 204.
The default configuration is the equivalent of:
{ "origin": "*", "methods": "GET,HEAD,PUT,PATCH,POST,DELETE", "preflightContinue": false, "optionsSuccessStatus": 204 }For details on the effect of each CORS header, read this article on web.dev.
Demo
A demo that illustrates CORS working (and not working) using React is available here: //node-cors-client.netlify.com
Code for that demo can be found here:
- Client: //github.com/troygoode/node-cors-client
- Server: //github.com/troygoode/node-cors-server
License
MIT License
Troy Goode ()