支持从浏览器调用的跨域资源共享(CORS)
要从浏览器调用边缘函数,你需要处理 CORS 预检 请求。
🌐 To invoke edge functions from the browser, you need to handle CORS Preflight requests.
自动处理 CORS #
🌐 Automatic CORS handling
withSupabase 封装器会帮你处理 CORS 和预检 (OPTIONS) 请求,所以你不用手动添加头信息:
🌐 The withSupabase wrapper handles CORS and preflight (OPTIONS) requests for you, so you don't add headers manually:
import { withSupabase } from 'npm:@supabase/server@^1'export default { fetch: withSupabase({ auth: 'user' }, async (req, ctx) => { const { name } = await req.json() return Response.json({ message: `Hello ${name}!` }) }),}手动处理 CORS #
🌐 Manual CORS handling
如果你的函数没有使用 withSupabase,就自己添加头文件。看看 GitHub 上的例子。
🌐 If your function doesn't use withSupabase, add the headers yourself. See the example on GitHub.
对于 @supabase/supabase-js v2.95.0 及更高版本: 直接从 SDK 导入 CORS 头,以确保它们与客户端库中添加的任何新头保持同步。
从 npm:@supabase/supabase-js@^2/cors 导入 corsHeaders,就能自动获取所有需要的头文件:
🌐 Import corsHeaders from npm:@supabase/supabase-js@^2/cors to automatically get all required headers:
import { corsHeaders } from 'npm:@supabase/supabase-js@^2/cors'console.log(`Function "browser-with-cors" up and running!`)export default { fetch: async (req) => { // Handle the CORS preflight request. if (req.method === 'OPTIONS') { return Response.json({ ok: true }, { headers: corsHeaders }) } try { const { name } = await req.json() return Response.json({ message: `Hello ${name}!` }, { headers: corsHeaders }) } catch (error) { const message = error instanceof Error ? error.message : String(error) return Response.json({ error: message }, { status: 400, headers: corsHeaders }) } },}从 SDK 导入可以让你的允许列表与客户端库发送的 headers 保持同步:当你在函数中升级 SDK 版本并重新部署时,新添加的 headers 会随之生效。从 @supabase/supabase-js v2.112.3 版本开始,列表中包括用于客户端追踪的 trace context headers(traceparent、tracestate、baggage)——使用旧版本部署的函数需要重新部署,浏览器才能在启用追踪传播的情况下调用它们。
🌐 Importing from the SDK keeps your allow-list aligned with the headers the client libraries send: when you upgrade the SDK version in your function and redeploy, newly added headers are picked up with it. As of @supabase/supabase-js v2.112.3 the list includes the trace context headers (traceparent, tracestate, baggage) used by client-side tracing — functions deployed with an older version need a redeploy before browsers can call them with trace propagation enabled.
允许列表只说明浏览器可以发送什么——它不会改变 SDK 发送的内容。跟踪上下文头只会由明确选择跟踪传播的客户端发送(tracePropagation: true,默认关闭)。没有选择加入的客户端发送的头信息和以前完全一样。
🌐 The allow-list only states what a browser may send — it doesn't change what the SDK sends. Trace context headers are sent exclusively by clients that explicitly opt in to trace propagation (tracePropagation: true, disabled by default). Clients that haven't opted in send exactly the same headers as before.
完整列表,以及每个标题何时发送:
🌐 The full list, and when each header is sent:
| 标题 | 发送 |
|---|---|
authorization | 每个请求(会话令牌或 API 密钥) |
apikey | 每个请求 |
x-client-info | 每个请求(SDK 名称和版本) |
content-type | 带有请求体的请求 |
x-retry-count | 仅在自动重试尝试时 (postgrest-js 默认重试失败的幂等请求) |
traceparent、tracestate、baggage | 仅在显式启用 trace 传播 时 — 默认情况下从不启用 |
在 2.95.0 之前的版本 #
🌐 For versions before 2.95.0
如果你在 v2.95.0 之前使用 @supabase/supabase-js,你需要硬编码 CORS 头。在 _shared 文件夹 中添加一个 cors.ts 文件。列表必须覆盖你调用的客户端发送的每个头——如果任何客户端启用了 tracePropagation,也要包括跟踪上下文头:
🌐 If you're using @supabase/supabase-js before v2.95.0, you'll need to hardcode the CORS headers. Add a cors.ts file within a _shared folder. The list must cover every header your calling clients send — include the trace context headers if any client enables tracePropagation:
export const = { 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Headers': 'authorization, x-client-info, apikey, content-type, x-retry-count, traceparent, tracestate, baggage', 'Access-Control-Allow-Methods': 'GET, POST, PUT, PATCH, DELETE, OPTIONS',}然后在你的函数中导入它:
🌐 Then import it in your function:
import { corsHeaders } from '../_shared/cors.ts'// ... rest of your function code