Skip to content

CORS 中间件

¥CORS Middleware

Cloudflare Workers 作为 Web API 有很多用例,可以从外部前端应用调用它们。对于它们,我们必须实现 CORS,让我们也使用中间件来做到这一点。

¥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

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

用法

¥Usage

ts
const app = new Hono()

// CORS should be called before the route
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:

ts
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'
    },
  })
)

基于源的动态允许方法:

¥Dynamic allowed methods based on origin:

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

选项

¥Options

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

"Access-Control-Allow-Origin" CORS 标头的值。你还可以传递像 origin: (origin) => (origin.endsWith('.example.com') ? origin : 'http://example.com') 这样的回调函数。默认为 *

¥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[] | (origin:string, c:Context) => string[]

"Access-Control-Allow-Methods" CORS 标头的值。你还可以传递回调函数,以根据来源动态确定允许的方法。默认为 ['GET', 'HEAD', 'PUT', 'POST', 'DELETE', 'PATCH']

¥The value of "Access-Control-Allow-Methods" CORS header. You can also pass a callback function to dynamically determine allowed methods based on the origin. The default is ['GET', 'HEAD', 'PUT', 'POST', 'DELETE', 'PATCH'].

optional allowHeaders:string[]

"Access-Control-Allow-Headers" CORS 标头的值。默认为 []

¥The value of "Access-Control-Allow-Headers" CORS header. The default is [].

optional maxAge:number

"Access-Control-Max-Age" CORS 标头的值。

¥The value of "Access-Control-Max-Age" CORS header.

optional 凭证:boolean

¥optional credentials: boolean

"Access-Control-Allow-Credentials" CORS 标头的值。

¥The value of "Access-Control-Allow-Credentials" CORS header.

optional 暴露标头:string[]

¥optional exposeHeaders: string[]

"Access-Control-Expose-Headers" CORS 标头的值。默认为 []

¥The value of "Access-Control-Expose-Headers" CORS header. The default is [].

依赖于环境的 CORS 配置

¥Environment-dependent CORS configuration

如果要根据执行环境(例如开发或生产)调整 CORS 配置,则从环境变量注入值很方便,因为它无需应用了解其自己的执行环境。有关说明,请参阅下面的示例。

¥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.

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

与 Vite 配合使用

¥Using with Vite

当将 Hono 与 Vite 一起使用时,你应该通过在 vite.config.ts 中将 server.cors 设置为 false 来禁用 Vite 内置的 CORS 功能。这可以避免与 Hono 的 CORS 中间件发生冲突。

¥When using Hono with Vite, you should disable Vite's built-in CORS feature by setting server.cors to false in your vite.config.ts. This prevents conflicts with Hono's CORS middleware.

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

export default defineConfig({
  server: {
    cors: false, // disable Vite's built-in CORS setting
  },
  plugins: [cloudflare()],
})

Hono v4.8 中文网 - 粤ICP备13048890号