API7 网关 AI Agent Skill:cors 插件
概览
cors 插件用于管理 API7 企业版上的跨源资源共享请求头
路由。它会自动处理预检 OPTIONS 请求,设置
Access-Control-* 响应头,并支持通配符、精确匹配和
基于正则表达式的来源匹配。
适用场景
- 允许浏览器 JavaScript 从不同来源访问你的 API
- 配置带凭证的跨源请求(Cookie、认证请求头)
- 通过正则表达式允许指定子域名
- 控制预检缓存时间以提升性能
插件配置参考(路由/服务)
| 字段 | 类型 | 是否必填 | 默认值 | 说明 |
|---|---|---|---|---|
allow_origins | string | 否 | "*" | 允许的来源。以逗号分隔,格式为 scheme://host:port。使用 * 表示允许所有来源(无凭证)。使用 ** 表示强制允许所有来源(存在安全风险)。 |
allow_methods | string | 否 | "*" | 允许的 HTTP 方法,逗号分隔。* 或 ** 的含义与 origins 相同 |
allow_headers | string | 否 | "*" | 允许的请求头,逗号分隔。为 ** 时回显请求的 Access-Control-Request-Headers |
expose_headers | string | 否 | — | 暴露给浏览器的响应头,逗号分隔。默认不设置 |
max_age | integer | 否 | 5 | 预检缓存时间,单位秒。-1 表示禁用缓存 |
allow_credential | boolean | 否 | false | 允许凭证(Cookie、认证请求头)。如果为 true,其他字段不能使用 *。 |
allow_origins_by_regex | array[string] | 否 | — | 用于动态匹配来源的正则表达式 |
allow_origins_by_metadata | array[string] | 否 | — | 从插件元数据引用来源 |
timing_allow_origins | string | 否 | — | 允许访问 Resource Timing API 的来源 |
timing_allow_origins_by_regex | array[string] | 否 | — | 用于匹配 timing origins 的正则表达式 |
通配符规则
| 值 | 含义 | 可与 allow_credential: true 一起使用? |
|---|---|---|
* | 允许全部 | ❌ CORS 规范不允许 |
** | 强制允许全部 | ✅ 允许,但存在风险(CSRF 风险) |
| 指定来源 | 精确匹配 | ✅ 允许 |
分步操作:在路由上启用 CORS
1. 基本 CORS(公开 API,无凭证)
a7 route create -g default -f - <<'EOF'
{
"id": "public-api",
"uri": "/api/*",
"plugins": {
"cors": {}
},
"upstream": {
"type": "roundrobin",
"nodes": [{"host": "backend", "port": 8080, "weight": 1}]
}
}
EOF
所有请求上的响应头:
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: *
Access-Control-Allow-Headers: *
Access-Control-Max-Age: 5
2. 带凭证的 CORS(指定来源)
a7 route create -g default -f - <<'EOF'
{
"id": "credentialed-api",
"uri": "/api/*",
"plugins": {
"cors": {
"allow_origins": "https://app.example.com,https://admin.example.com",
"allow_methods": "GET,POST,PUT,DELETE,OPTIONS",
"allow_headers": "Content-Type,Authorization,X-Custom-Header",
"expose_headers": "X-Request-Id,X-Response-Time",
"max_age": 3600,
"allow_credential": true
}
},
"upstream": {
"type": "roundrobin",
"nodes": [{"host": "backend", "port": 8080, "weight": 1}]
}
}
EOF
常见模式
基于正则表达式匹配来源(所有子域)
{
"plugins": {
"cors": {
"allow_origins_by_regex": [
".*\\.example\\.com$"
],
"allow_methods": "GET,POST,PUT,DELETE",
"allow_credential": true,
"max_age": 86400
}
}
}
匹配:https://app.example.com、https://staging.example.com
不匹配:https://example.com、https://evil.com
使用正则表达式匹配多个域名组
{
"plugins": {
"cors": {
"allow_origins_by_regex": [
".*\\.example\\.com$",
".*\\.partner\\.net$",
"^https://localhost:[0-9]+$"
],
"allow_methods": "GET,POST",
"allow_credential": true
}
}
}
较长的预检缓存
{
"plugins": {
"cors": {
"allow_origins": "https://app.example.com",
"max_age": 86400,
"allow_credential": true
}
}
}
浏览器会缓存预检响应 24 小时,从而减少 OPTIONS 请求。
暴露自定义响应头
{
"plugins": {
"cors": {
"allow_origins": "*",
"expose_headers": "X-Request-Id,X-RateLimit-Limit,X-RateLimit-Remaining"
}
}
}
如果未设置 expose_headers,浏览器只会暴露 CORS 安全列表响应头。
插件设置的响应头
| 请求头 | 设置时机 |
|---|---|
Access-Control-Allow-Origin | 始终设置(匹配来源或 *) |
Access-Control-Allow-Methods | 始终设置 |
Access-Control-Allow-Headers | 始终设置 |
Access-Control-Expose-Headers | 仅在配置 expose_headers 时设置 |
Access-Control-Max-Age | 始终设置(预检响应) |
Access-Control-Allow-Credentials | 仅在 allow_credential: true 时设置 |
Timing-Allow-Origin | 仅在配置 timing_allow_origins 时设置 |
故障排查
| 现象 | 原因 | 修复方式 |
|---|---|---|
| 已启用插件但浏览器仍报 CORS 错误 | allow_credential: true 与 allow_origins: "*" 同时使用 | 使用具体来源或 **(有风险) |
| 预检失败但 GET 可用 | allow_methods 缺少对应方法 | 将该方法添加到 allow_methods |
| 自定义请求头被拦截 | 请求头不在 allow_headers 中 | 将请求头添加到 allow_headers |
| JS 无法读取响应头 | 响应头不在 expose_headers 中 | 将响应头添加到 expose_headers |
| 正则未匹配 | 缺少锚点或转义 | 使用 $ 锚点并转义点号:\. |
| 跨源请求未发送 Cookie | allow_credential 为 false | 设置 allow_credential: true 并使用具体来源 |
| 来源格式被拒绝 | 缺少 scheme | 使用 https://example.com,不要使用 example.com |
配置同步示例
version: "1"
gateway_groups:
- name: default
routes:
- id: cors-api
uri: /api/*
plugins:
cors:
allow_origins: "https://app.example.com"
allow_methods: "GET,POST,PUT,DELETE,OPTIONS"
allow_headers: "Content-Type,Authorization"
expose_headers: "X-Request-Id"
max_age: 3600
allow_credential: true
upstream:
type: roundrobin
nodes:
- host: backend
port: 8080
weight: 1
本页面由 api7/a7 仓库中的 a7-plugin-cors/SKILL.md 生成。你可以在 AI Agent Skills 页面查看所有技能。