如何在 Pages Functions 上启用 CORS?

8 分钟阅读
Spt 8, 2025
跨域资源共享(CORS)是浏览器实现的一种安全机制,用于控制 Web 应用程序如何与不同源的资源交互。默认情况下,同源策略限制 Web 页面向其他域的服务器发起请求。CORS 通过允许服务器使用 HTTP 响应头来指定哪些源可以访问其资源,从而有选择地放宽这一限制。
关键 CORS 响应头及其功能
- Access-Control-Allow-Origin: 指定允许访问资源的源。使用 * 允许所有源(不建议用于敏感数据);指定特定源(例如,https://app.example)可以提高安全性。
- Access-Control-Allow-Methods: 列出访问资源时允许的 HTTP 方法(例如,GET,POST,PUT,PATCH,DELETE,OPTIONS)。
- 指定可以包含在实际请求中的自定义头(例如,Authorization,Content-Type,X-CSRF-Token)。
- Access-Control-Allow-Credentials: 指示是否允许凭证(例如,cookies 或 HTTP 身份验证)。必须设置为 true,并且只能与显式(非 * )源一起使用。
- Access-Control-Max-Age: 定义预检请求的结果可以由浏览器缓存的时间(以秒为单位)(例如,86400 表示 24 小时)。
当请求被视为“非简单请求”(例如使用自定义头或其他方法而非 GET/POST)时,浏览器会自动向服务器发送预检 OPTIONS 请求。服务器必须返回适当的 CORS 头;否则,浏览器将阻止实际请求。
通过 Pages Functions 解决跨源问题
Pages Functions 提供了一个无服务器代码执行环境,运行在 EdgeOne 边缘节点上。开发者只需编写业务逻辑并配置触发规则——无需管理服务器基础设施。代码在靠近终端的边缘节点上弹性安全地执行。
通过 headers API 解决 CORS
典型代码示例:
// functions/api/hello.ts
export async function onRequest({ request }) {
const origin = request.headers.get("Origin");
// 业务逻辑或代理上游请求
const response = await fetch(request);
// 设置CORS响应头
response.headers.set("Access-Control-Allow-Origin", origin || "*");
response.headers.set("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
response.headers.set("Access-Control-Allow-Headers", "Content-Type, Authorization");
response.headers.set("Access-Control-Max-Age", "86400");
return response;
}
注意:如果需要支持凭证(例如 cookies),必须将 Access-Control-Allow-Origin
设置为特定域,并添加 true
。
基于地理位置的 CORS
您还可以使用 EdgeOne 的地理位置信息实施区域特定的 CORS 策略:
// functions/api/hello.ts
export async function onRequest({ request }) {
const origin = request.headers.get("Origin");
const country = (request.eo.geo && request.eo.geo.country) || "US";
const corsMap = {
US: { origins: ["https://us.example.com"], credentials: true },
CA: { origins: ["https://ca.example.com"], credentials: true },
EU: { origins: ["https://eu.example.com"], credentials: true },
};
const region = corsMap[country] || { origins: ["https://global.example.com"], credentials: false };
const isAllowed = origin && region.origins.includes(origin);
const headers = {
"Access-Control-Allow-Origin": isAllowed ? origin : "null",
"Access-Control-Allow-Methods": "GET, POST, OPTIONS",
"Access-Control-Allow-Headers": "Content-Type, Authorization",
"Access-Control-Allow-Credentials": region.credentials.toString(),
"Access-Control-Max-Age": "86400",
};
if (request.method === "OPTIONS") {
return new Response(null, { status: 204, headers });
}
return new Response(JSON.stringify({ country }), {
headers: { ...headers, "content-type": "application/json; charset=UTF-8" },
});
}
测试您的设置
# 预检
curl -i -X OPTIONS https://your-domain.edgeone.app/api/hello \
-H "Origin: https://app.example" \
-H "Access-Control-Request-Method: POST"
# 简单请求
curl -i https://your-domain.edgeone/api/hello \
-H "Origin: https://app.example"
查看200
状态的 OPTIONS 调用和两个响应中的正确 CORS 头。
常见 CORS 场景和解决方案
- 从本地前端开发调用 API 时的 CORS 错误:API 服务器必须包含允许本地开发域的 CORS 头。
- 第三方应用集成您的 API:动态确定
Origin
并根据需要返回相应的 CORS 头以增强安全性。 - 支持凭证的跨源请求:
Access-Control-Allow-Credentials
必须设置为true
,并且Access-Control-Allow-Origin
不能为*
。
总结
CORS 是在前端/后端分离和微服务架构中不可避免的问题。通过灵活地在 EdgeOne Pages Functions 中设置 CORS 响应头,您可以有效且安全地满足跨源访问要求。对于更复杂的场景,您可以利用环境变量、KV 存储和其他功能来实现动态授权和个性化的跨源策略。
有关高级用法,请参阅 Pages Functions 文档。