Skip to content

CORS 中间件

Cloudflare Workers 常被用来提供 Web API,并由外部前端调用。 这类场景需要实现 CORS,我们同样可以通过中间件来完成。

导入

ts
import { Hono } from 'hono'
import { cors } from 'hono/cors'

用法

ts
const app = new Hono()

// CORS 中间件需在路由之前调用
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 })
})

多个允许来源:

ts
app.use(
  '/api3/*',
  cors({
    origin: ['https://example.com', 'https://example.org'],
  })
)

// 也可以传入函数
app.use(
  '/api4/*',
  cors({
    // `c` 为 `Context` 对象
    origin: (origin, c) => {
      return origin.endsWith('.example.com')
        ? origin
        : 'http://example.com'
    },
  })
)

基于来源动态决定允许的方法:

ts
app.use(
  '/api5/*',
  cors({
    origin: (origin) =>
      origin === 'https://example.com' ? origin : '*',
    // `c` 为 `Context` 对象
    allowMethods: (origin, c) =>
      origin === 'https://example.com'
        ? ['GET', 'HEAD', 'POST', 'PATCH', 'DELETE']
        : ['GET', 'HEAD'],
  })
)

选项

optional origin:string | string[] | (origin: string, c: Context) => string

对应 CORS 头 _Access-Control-Allow-Origin_ 的值。也可以传入回调函数,例如 origin: (origin) => (origin.endsWith('.example.com') ? origin : 'http://example.com')。默认值为 *

optional allowMethods:string[] | (origin: string, c: Context) => string[]

对应 _Access-Control-Allow-Methods_ 头的值。也可以传入回调函数,根据来源动态决定允许的方法。默认值为 ['GET', 'HEAD', 'PUT', 'POST', 'DELETE', 'PATCH']

optional allowHeaders:string[]

对应 _Access-Control-Allow-Headers_ 头的值。默认值为 []

optional maxAge:number

对应 _Access-Control-Max-Age_ 头的值。

optional credentials:boolean

对应 _Access-Control-Allow-Credentials_ 头的值。

optional exposeHeaders:string[]

对应 _Access-Control-Expose-Headers_ 头的值。默认值为 []

根据环境配置 CORS

若希望根据运行环境(如开发/生产)调整 CORS 配置,注入环境变量是一种方便方式,可避免让应用自行判断运行环境。示例如下:

ts
app.use('*', async (c, next) => {
  const corsMiddlewareHandler = cors({
    origin: c.env.CORS_ORIGIN,
  })
  return corsMiddlewareHandler(c, next)
})

搭配 Vite 使用

如果在 Vite 中使用 Hono,需要在 vite.config.ts 中将 server.cors 设为 false,以禁用 Vite 自带的 CORS 功能,从而避免与 Hono 的 CORS 中间件冲突。

ts
// vite.config.ts
import { cloudflare } from '@cloudflare/vite-plugin'
import { defineConfig } from 'vite'

export default defineConfig({
  server: {
    cors: false, // 禁用 Vite 内建的 CORS 设置
  },
  plugins: [cloudflare()],
})

Released under the MIT License.