CORS is a node.js package for providing aConnect/Expressmiddleware that can be used to enableCORSwith various options.
Follow me (@troygoode) on Twitter!
This is aNode.jsmodule available through the
npm registry.Installation is done using the
npm install
command:
$ npm install cors
varexpress=require('express')
varcors=require('cors')
varapp=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')
})
varexpress=require('express')
varcors=require('cors')
varapp=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')
})
varexpress=require('express')
varcors=require('cors')
varapp=express()
varcorsOptions={
origin:'http://example ',
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.'})
})
app.listen(80,function(){
console.log('CORS-enabled web server listening on port 80')
})
This module supports validating the origin dynamically using a function provided
to theorigin
option. This function will be passed a string that is the origin
(orundefined
if the request has no origin), and acallback
with the signature
callback(error, origin)
.
Theorigin
argument to the callback can be any value allowed for theorigin
option of the middleware, except a function. See the
configuration optionssection 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.
varexpress=require('express')
varcors=require('cors')
varapp=express()
varcorsOptions={
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')
})
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:
varexpress=require('express')
varcors=require('cors')
varapp=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 routes
NOTE: When using this middleware as an application level middleware (for
example,app.use(cors())
), pre-flight requests are already handled for all
routes.
varexpress=require('express')
varcors=require('cors')
varapp=express()
varallowlist=['http://example1 ','http://example2 ']
varcorsOptionsDelegate=function(req,callback){
varcorsOptions;
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')
})
origin
:Configures theAccess-Control-Allow-OriginCORS header. Possible values:Boolean
- setorigin
totrue
to reflect therequest origin,as defined byreq.header('Origin')
,or set it tofalse
to disable CORS.String
- setorigin
to a specific origin. For example if you set it to"http://example"
only requests from "http://example"will be allowed.RegExp
- setorigin
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\ $/
will reflect any request that is coming from an origin ending with "example".Array
- setorigin
to an array of valid origins. Each origin can be aString
or aRegExp
.For example[ "http://example1", /\.example2\ $/]
will accept any request from "http://example1"or from a subdomain of" example2 ".Function
- setorigin
to a function implementing some custom logic. The function takes the request origin as the first parameter and a callback (called ascallback(err, origin)
,whereorigin
is a non-function value of theorigin
option) as the second.
methods
:Configures theAccess-Control-Allow-MethodsCORS header. Expects a comma-delimited string (ex: 'GET,PUT,POST') or an array (ex:['GET', 'PUT', 'POST']
).allowedHeaders
:Configures theAccess-Control-Allow-HeadersCORS 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'sAccess-Control-Request-Headersheader.exposedHeaders
:Configures theAccess-Control-Expose-HeadersCORS 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 theAccess-Control-Allow-CredentialsCORS header. Set totrue
to pass the header, otherwise it is omitted.maxAge
:Configures theAccess-Control-Max-AgeCORS 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 successfulOPTIONS
requests, since some legacy browsers (IE11, various SmartTVs) choke on204
.
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, readthisarticle on web.dev.
A demo that illustrates CORS working (and not working) using React is available here:https://node-cors-client.netlify
Code for that demo can be found here: