跳到主要内容
版本:3.10.x

API7 网关 AI Agent Skill:cors 插件

概览

cors 插件用于管理 API7 企业版上的跨源资源共享请求头 路由。它会自动处理预检 OPTIONS 请求,设置 Access-Control-* 响应头,并支持通配符、精确匹配和 基于正则表达式的来源匹配。

适用场景

  • 允许浏览器 JavaScript 从不同来源访问你的 API
  • 配置带凭证的跨源请求(Cookie、认证请求头)
  • 通过正则表达式允许指定子域名
  • 控制预检缓存时间以提升性能

插件配置参考(路由/服务)

字段类型是否必填默认值说明
allow_originsstring"*"允许的来源。以逗号分隔,格式为 scheme://host:port。使用 * 表示允许所有来源(无凭证)。使用 ** 表示强制允许所有来源(存在安全风险)。
allow_methodsstring"*"允许的 HTTP 方法,逗号分隔。*** 的含义与 origins 相同
allow_headersstring"*"允许的请求头,逗号分隔。为 ** 时回显请求的 Access-Control-Request-Headers
expose_headersstring暴露给浏览器的响应头,逗号分隔。默认不设置
max_ageinteger5预检缓存时间,单位秒。-1 表示禁用缓存
allow_credentialbooleanfalse允许凭证(Cookie、认证请求头)。如果为 true,其他字段不能使用 *
allow_origins_by_regexarray[string]用于动态匹配来源的正则表达式
allow_origins_by_metadataarray[string]从插件元数据引用来源
timing_allow_originsstring允许访问 Resource Timing API 的来源
timing_allow_origins_by_regexarray[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.comhttps://staging.example.com 不匹配:https://example.comhttps://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: trueallow_origins: "*" 同时使用使用具体来源或 **(有风险)
预检失败但 GET 可用allow_methods 缺少对应方法将该方法添加到 allow_methods
自定义请求头被拦截请求头不在 allow_headers将请求头添加到 allow_headers
JS 无法读取响应头响应头不在 expose_headers将响应头添加到 expose_headers
正则未匹配缺少锚点或转义使用 $ 锚点并转义点号:\.
跨源请求未发送 Cookieallow_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 页面查看所有技能。