Appearance
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()],
})