CORS Middleware
There are many use cases of Cloudflare Workers as Web APIs and calling them from external front-end application. For them we have to implement CORS, let's do this with middleware as well.
Import
import { Hono } from 'hono'
import { cors } from 'hono/cors'
Usage
const app = new Hono()
app.use('/api/*', cors())
app.use(
'/api2/*',
cors({
origin: 'http://example.com',
allowHeaders: ['X-Custom-Header', 'Upgrade-Insecure-Requests'],
allowMethods: ['POST', 'GET', 'OPTIONS'],
exposeHeaders: ['Content-Length', 'X-Kuma-Revision'],
maxAge: 600,
credentials: true,
})
)
app.all('/api/abc', (c) => {
return c.json({ success: true })
})
app.all('/api2/abc', (c) => {
return c.json({ success: true })
})
Multiple origins:
app.use(
'/api3/*',
cors({
origin: ['https://example.com', 'https://example.org'],
})
)
// Or you can use "function"
app.use(
'/api4/*',
cors({
// `c` is a `Context` object
origin: (origin, c) => {
return origin.endsWith('.example.com')
? origin
: 'http://example.com'
},
})
)
Options
optional origin: string
| string[]
| (origin:string, c:Context) => string
The value of "Access-Control-Allow-Origin" CORS header. You can also pass the callback function like origin: (origin) => (origin.endsWith('.example.com') ? origin : 'http://example.com')
. The default is *
.
optional allowMethods: string[]
The value of "Access-Control-Allow-Methods" CORS header. The default is ['GET', 'HEAD', 'PUT', 'POST', 'DELETE', 'PATCH']
.
optional allowHeaders: string[]
The value of "Access-Control-Allow-Headers" CORS header. The default is []
.
optional maxAge: number
The value of "Access-Control-Max-Age" CORS header.
optional credentials: boolean
The value of "Access-Control-Allow-Credentials" CORS header.
optional exposeHeaders: string[]
The value of "Access-Control-Expose-Headers" CORS header. The default is []
.
Environment-dependent CORS configuration
If you want to adjust CORS configuration according to the execution environment, such as development or production, injecting values from environment variables is convenient as it eliminates the need for the application to be aware of its own execution environment. See the example below for clarification.
app.use('*', async (c, next) => {
const corsMiddlewareHandler = cors({
origin: c.env.CORS_ORIGIN,
})
return corsMiddlewareHandler(c, next)
})