@fastify/cors
enables the use of CORS in a Fastify application.
npm i @fastify/cors
Plugin version | Fastify version |
---|---|
^10.x |
^5.x |
^8.x |
^4.x |
^7.x |
^3.x |
^3.x |
^2.x |
^1.x |
^1.x |
Please note that if a Fastify version is out of support, then so are the corresponding versions of this plugin in the table above. See Fastify's LTS policy for more details.
Require @fastify/cors
and register it as any other plugin. It adds an onRequest
hook and a wildcard options route.
import Fastify from 'fastify'
import cors from '@fastify/cors'
const fastify = Fastify()
await fastify.register(cors, {
// put your options here
})
fastify.get('/', (req, reply) => {
reply.send({ hello: 'world' })
})
await fastify.listen({ port: 3000 })
You can use it as is without passing any option or you can configure it as explained below.
origin
: Configures the Access-Control-Allow-Origin CORS header. The value of origin can be:Boolean
: Set totrue
to reflect the request origin, orfalse
to disable CORS.String
: Set to a specific origin (e.g.,"http://example.com"
). The special*
value (default) allows any origin.RegExp
: Set to a regular expression pattern to test the request origin. If it matches, the request origin is reflected (e.g.,/example\.com$/
returns the origin only if it ends withexample.com
).Array
: Set to an array of valid origins, each being aString
orRegExp
(e.g.,["http://example1.com", /\.example2\.com$/]
).Function
: Set to a function with custom logic. The function takes the request origin as the first parameter and a callback as the second (signatureerr [Error | null], origin
). Async-await and promises are supported. The Fastify instance is bound to the function call and can be accessed viathis
. For example:
origin: (origin, cb) => { const hostname = new URL(origin).hostname if(hostname === "localhost"){ // Request from localhost will pass cb(null, true) return } // Generate an error on other origins, disabling access cb(new Error("Not allowed"), false) }
methods
: Configures the Access-Control-Allow-Methods CORS header. Expects a comma-delimited string (e.g., 'GET,PUT,POST') or an array (e.g.,['GET', 'PUT', 'POST']
). Default:GET,HEAD,PUT,PATCH,POST,DELETE
.hook
: See Custom Fastify hook name. Default:onRequest
.allowedHeaders
: Configures the Access-Control-Allow-Headers CORS header. Expects a comma-delimited string (e.g.,'Content-Type,Authorization'
) or an array (e.g.,['Content-Type', 'Authorization']
). Defaults to reflecting the headers specified in the request's Access-Control-Request-Headers header if not specified.exposedHeaders
: Configures the Access-Control-Expose-Headers CORS header. Expects a comma-delimited string (e.g.,'Content-Range,X-Content-Range'
) or an array (e.g.,['Content-Range', 'X-Content-Range']
). No custom headers are exposed if not specified.credentials
: Configures the Access-Control-Allow-Credentials CORS header. Set totrue
to pass the header; otherwise, it is omitted.maxAge
: Configures the Access-Control-Max-Age CORS header in seconds. Set to an integer to pass the header; otherwise, it is omitted.cacheControl
: Configures the Cache-Control header for CORS preflight responses. Set to an integer to pass the header asCache-Control: max-age=${cacheControl}
, or set to a string to pass the header asCache-Control: ${cacheControl}
. Otherwise, the header is omitted.preflightContinue
: Passes the CORS preflight response to the route handler. Default:false
.optionsSuccessStatus
: Provides a status code for successfulOPTIONS
requests, as some legacy browsers (IE11, various SmartTVs) choke on204
.preflight
: Disables preflight by passingfalse
. Default:true
.strictPreflight
: Enforces strict requirements for the CORS preflight request headers (Access-Control-Request-Method and Origin) as defined by the W3C CORS specification. Preflight requests without the required headers result in 400 errors when set totrue
. Default:true
.hideOptionsRoute
: Hides the options route from documentation built using @fastify/swagger. Default:true
.
Using RegExp
or a function
for the origin
parameter may enable Denial of Service attacks.
Craft with extreme care.
const fastify = require('fastify')()
fastify.register(require('@fastify/cors'), (instance) => {
return (req, callback) => {
const corsOptions = {
// This is NOT recommended for production as it enables reflection exploits
origin: true
};
// do not include CORS headers for requests from localhost
if (/^localhost$/m.test(req.headers.origin)) {
corsOptions.origin = false
}
// callback expects two parameters: error and options
callback(null, corsOptions)
}
})
fastify.register(async function (fastify) {
fastify.get('/', (req, reply) => {
reply.send({ hello: 'world' })
})
})
fastify.listen({ port: 3000 })
By default, @fastify/cors
adds an onRequest
hook for validation and header injection. This can be customized by passing hook
in the options. Valid values are onRequest
, preParsing
, preValidation
, preHandler
, preSerialization
, and onSend
.
import Fastify from 'fastify'
import cors from '@fastify/cors'
const fastify = Fastify()
await fastify.register(cors, {
hook: 'preHandler',
})
fastify.get('/', (req, reply) => {
reply.send({ hello: 'world' })
})
await fastify.listen({ port: 3000 })
To configure CORS asynchronously, provide an object with the delegator
key:
const fastify = require('fastify')()
fastify.register(require('@fastify/cors'), {
hook: 'preHandler',
delegator: (req, callback) => {
const corsOptions = {
// This is NOT recommended for production as it enables reflection exploits
origin: true
};
// do not include CORS headers for requests from localhost
if (/^localhost$/m.test(req.headers.origin)) {
corsOptions.origin = false
}
// callback expects two parameters: error and options
callback(null, corsOptions)
},
})
fastify.register(async function (fastify) {
fastify.get('/', (req, reply) => {
reply.send({ hello: 'world' })
})
})
fastify.listen({ port: 3000 })
The code is a port for Fastify of expressjs/cors
.
Licensed under MIT.
expressjs/cors
license