itty-router
CORS
Everyone’s favorite topic.
Handling CORS requests in itty is a little different than many traditional routers, since we don’t build the Response over a series of middlewares and handlers. Because of that, our createCors(options?)
helper returns a pair of handlers, preflight
and corsify
.
preflight (middleware)
We recommend embedding this upstream on the .all('*')
path of any CORS-enabled router/branch. Doing so handles all OPTIONS and preflight requests.
import { Router, createCors, error, json } from 'itty-router'
const { preflight, corsify } = createCors()
const router = Router()
router
// embed preflight upstream to handle all OPTIONS requests
.all('*', preflight)
corsify
This function simply adds the appropriate CORS headers to any Response.
corsify(response: Response): Response
// creates a JSON Response *without* CORS headers
json({ foo: 'bar' })
// creates a JSON Response *with* CORS headers
corsify(json({ foo: 'bar' }))
While you can wrap any specific Response with the corsify
function, we recommend simply adding this downstream onto the outermost router.handle
chain, transforming all Responses on their way out of the API.
router
.handle(request, ...args)
// turn any returned raw data into JSON
.then(json)
// catch errors BEFORE corsify
.catch(error)
// corsify all Responses (including errors)
.then(corsify)
Configuring CORS
In order to facilitate different CORS setups, all the usual CORS options are available when using createCors
to create your CORS pair. The following table describes the available options:
Name | Type(s) | Default | Description |
---|---|---|---|
origins | string[] |
["*"] |
the list of acceptable origins |
methods | string[] |
["GET"] |
list of CORS-allowed HTTP methods |
maxAge | number |
undefined |
max-age, in seconds, for CORS headers |
headers | object |
undefined |
list of headers to manually inject into all CORS Responses (via both preflight and corsify ) |
Complete Example
import { createCors, error, json, Router } from 'itty-router'
import { otherRouter } from './api/v1'
// create the CORS pair
const { preflight, corsify } = createCors({
methods: ['GET', 'PATCH', 'POST'],
origins: ['http://localhost:3000'],
headers: {
'my-funky-header': 'is pretty funky indeed',
},
})
// create a router
const router = Router()
router
// register the preflight middleware
.all('*', preflight)
// add some routes, another router, etc.
.all('/v1/*', otherRouter.handle)
// catch missed routes
.all('*', () => error(404))
export default {
fetch: (request) => router
.handle(request)
// transform unformed responses
.then(json)
// catch any errors
.catch(error)
// add CORS headers to all requests,
// including errors
.then(corsify)
}