0
0
mirror of https://github.com/honojs/hono.git synced 2024-12-01 10:51:01 +00:00
hono/deno_dist/middleware/cors/index.ts

94 lines
2.6 KiB
TypeScript
Raw Normal View History

import type { MiddlewareHandler } from '../../types.ts'
2022-07-02 06:09:45 +00:00
type CORSOptions = {
origin: string | string[] | ((origin: string) => string | undefined | null)
2022-07-02 06:09:45 +00:00
allowMethods?: string[]
allowHeaders?: string[]
maxAge?: number
credentials?: boolean
exposeHeaders?: string[]
}
export const cors = (options?: CORSOptions): MiddlewareHandler => {
2022-07-02 06:09:45 +00:00
const defaults: CORSOptions = {
origin: '*',
allowMethods: ['GET', 'HEAD', 'PUT', 'POST', 'DELETE', 'PATCH'],
allowHeaders: [],
exposeHeaders: [],
}
const opts = {
...defaults,
...options,
}
const findAllowOrigin = ((optsOrigin) => {
if (typeof optsOrigin === 'string') {
return () => optsOrigin
} else if (typeof optsOrigin === 'function') {
return optsOrigin
} else {
return (origin: string) => (optsOrigin.includes(origin) ? origin : optsOrigin[0])
}
})(opts.origin)
return async (c, next) => {
2022-07-02 06:09:45 +00:00
function set(key: string, value: string) {
c.res.headers.append(key, value)
}
const allowOrigin = findAllowOrigin(c.req.headers.get('origin') || '')
if (allowOrigin) {
set('Access-Control-Allow-Origin', allowOrigin)
}
2022-07-02 06:09:45 +00:00
// Suppose the server sends a response with an Access-Control-Allow-Origin value with an explicit origin (rather than the "*" wildcard).
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin
if (opts.origin !== '*') {
set('Vary', 'Origin')
}
if (opts.credentials) {
set('Access-Control-Allow-Credentials', 'true')
}
if (opts.exposeHeaders?.length) {
set('Access-Control-Expose-Headers', opts.exposeHeaders.join(','))
}
if (c.req.method !== 'OPTIONS') {
await next()
} else {
2022-07-02 06:09:45 +00:00
// Preflight
if (opts.maxAge != null) {
set('Access-Control-Max-Age', opts.maxAge.toString())
}
if (opts.allowMethods?.length) {
set('Access-Control-Allow-Methods', opts.allowMethods.join(','))
}
let headers = opts.allowHeaders
if (!headers?.length) {
const requestHeaders = c.req.headers.get('Access-Control-Request-Headers')
if (requestHeaders) {
headers = requestHeaders.split(/\s*,\s*/)
}
}
if (headers?.length) {
set('Access-Control-Allow-Headers', headers.join(','))
set('Vary', 'Access-Control-Request-Headers')
}
c.res.headers.delete('Content-Length')
c.res.headers.delete('Content-Type')
return new Response(null, {
2022-07-02 06:09:45 +00:00
headers: c.res.headers,
status: 204,
statusText: c.res.statusText,
})
}
}
}