CORS 政策

本页面适用于 ApigeeApigee Hybrid

查看 Apigee Edge 文档。

内容

跨源资源共享 (CORS) 是一种标准机制,允许在网页中执行的 JavaScript XMLHttpRequest (XHR) 调用与来自非源网域的资源进行交互。CORS 是通常针对所有浏览器强制执行的同源政策实现的解决方案。

例如,如果您从浏览器执行的 JavaScript 代码向 Twitter API 发出 XHR 调用,则该调用将失败。这是因为为浏览器提供网页的网域与为 Twitter API 提供服务的网域不同。CORS 针对这个问题提供了一个解决方案,允许服务器在希望提供跨源资源共享的情况下选择加入

此 CORS 政策允许 Apigee 客户为 Web 应用使用的 API 设置 CORS 政策。

此政策为标准政策,可部署到任何环境类型。如需了解政策类型以及在每种环境类型中的可用性,请参阅政策类型

<CORS> 元素

定义 CORS 政策。

默认值 请参阅下面的默认政策标签页
是否必需? 必需
类型 复杂对象
父元素 不适用
子元素 <AllowCredentials>
<AllowHeaders>
<AllowMethods>
<AllowOrigins>
<DisplayName>
<ExposeHeaders>
<GeneratePreflightResponse>
<IgnoreUnresolvedVariables>
<MaxAge>

<CORS> 元素使用以下语法:

语法

<CORS> 元素使用以下语法:


<CORS continueOnError="[false|true]" enabled="[false|true]" name="POLICY_NAME">
  <DisplayName>DISPLAY_NAME</DisplayName>
  <AllowOrigins>[{message template}|URL|URL, URL, ...|{context-variable}|{flow-variable}|*]</AllowOrigins>
  <AllowMethods>[GET, PUT, POST, DELETE, ...|*]</AllowMethods>
  <AllowHeaders>[origin, x-requested-with, accept, content-type, ...]</AllowHeaders>
  <ExposeHeaders>[X-CUSTOM-HEADER-A, X-CUSTOM-HEADER-B, ... | *]</ExposeHeaders>
  <MaxAge>[integer|-1]</MaxAge>
  <AllowCredentials>[false|true]</AllowCredentials>
  <GeneratePreflightResponse>[false|true]</GeneratePreflightResponse>
  <IgnoreUnresolvedVariables>[false|true]</IgnoreUnresolvedVariables>
</CORS>

默认政策

以下示例显示了在 Edge 界面中将 CORS 政策添加到流时的默认设置:

<CORS continueOnError="false" enabled="true" name="add-cors">
    <DisplayName>Add CORS</DisplayName>
    <AllowOrigins>{request.header.origin}</AllowOrigins>
    <AllowMethods>GET, PUT, POST, DELETE</AllowMethods>
    <AllowHeaders>origin, x-requested-with, accept, content-type</AllowHeaders>
    <ExposeHeaders>*</ExposeHeaders>
    <MaxAge>3628800</MaxAge>
    <AllowCredentials>false</AllowCredentials>
    <GeneratePreflightResponse>true</GeneratePreflightResponse>
    <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
</CORS>

当您在 Apigee 界面中插入新的 CORS 政策时,该模板将包含所有可能操作的存根。您通常可以选择要对此政策执行的操作,并移除其余的子元素。例如,如果要指定允许访问资源的 HTTP 方法,请使用 <AllowMethods> 元素并从政策中移除其他子元素以提高其可读性。

此元素具有所有政策中常见的以下属性:

属性 默认 是否必需? 说明
name 不适用 必需

政策的内部名称。name 属性的值可以包含字母、数字、空格、连字符、下划线和英文句点。此值不能超过 255 个字符。

(可选)使用 <DisplayName> 元素在管理界面代理编辑器中给政策添加不同的自然语言名称标签。

continueOnError false 可选 设置为 false 可在政策失败时返回错误。这是大多数政策的预期行为。设置为 true,即使在政策失败后,仍可以继续执行流。另请参阅:
enabled true 可选 设置为 true 可实施政策。 设为 false 可关闭政策。即使政策仍附加到某个流,也不会强制执行该政策。
async   false 已弃用 此属性已弃用。

后续各部分介绍了每个子元素。

示例

以下部分提供了所有子元素的示例。

子元素参考

本部分介绍 <CORS> 的子元素。

<AllowCredentials>

指示是否允许调用方使用凭据发送实际请求(而不是预检)。转换为 Access-Control-Allow-Credentials 标头。

默认值 如果未指定该项,则不会设置 Access-Control-Allow-Credentials
是否必需? 可选
类型 布尔值
父元素 <CORS>
子元素

<AllowCredentials> 元素使用以下语法:

语法

<CORS continueOnError="[false|true]" enabled="[false|true]" name="POLICY_NAME">
  <AllowOrigins>[{message template}|URL|URL, URL, ...|{context-variable}|{flow-variable}|*]</AllowOrigins>
  <AllowCredentials>[false|true]</AllowCredentials>
</CORS>
      

示例

此示例将 Access-Control-Allow-Credentials 标头设置为 false。也就是说,不允许调用方使用凭据发送实际请求(不是预检)。

<CORS continueOnError="false" enabled="true" name="add-cors">
  <AllowOrigins>{request.header.origin}</AllowOrigins>
  <AllowCredentials>false</AllowCredentials>
</CORS>

<AllowHeaders>

请求资源时可以使用的 HTTP 标头列表。序列化Access-Control-Allow-Headers 标头。

默认值 Origin, Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers
是否必需? 可选
类型 字符串(支持消息模板*)
父元素 <CORS>
子元素

*如需了解详情,请参阅什么是消息模板?

<AllowHeaders> 元素使用以下语法:

语法

<CORS continueOnError="[false|true]" enabled="[false|true]" name="POLICY_NAME">
  <AllowOrigins>[{message template}|URL|URL, URL, ...|{context-variable}|{flow-variable}|*]</AllowOrigins>
  <AllowHeaders>[origin, x-requested-with, accept, content-type, ...]</AllowHeaders>
</CORS>

示例

CORS AllowOrigins 示例

此示例指定请求资源时可以使用的 HTTP 标头。

<CORS continueOnError="false" enabled="true" name="add-cors">
  <AllowOrigins>{request.header.origin}</AllowOrigins>
  <AllowHeaders>origin, x-requested-with, accept, content-type</AllowHeaders>
</CORS>

<AllowMethods>

允许访问资源的 HTTP 方法列表。该内容将序列化Access-Control-Allow-Methods 标头中。

默认值 GET, POST, HEAD, OPTIONS
是否必需? 可选
类型 字符串(支持消息模板*)
父元素 <CORS>
子元素

*如需了解详情,请参阅什么是消息模板?

<AllowMethods> 元素使用以下语法:

语法

<CORS continueOnError="[false|true]" enabled="[false|true]" name="POLICY_NAME">
  <AllowOrigins>[{message template}|URL|URL, URL, ...|{context-variable}|{flow-variable}|*]</AllowOrigins>
  <AllowMethods>[GET, PUT, POST, DELETE, ...|*]</AllowMethods>
</CORS>

示例:
列表

此示例指定允许访问资源的 HTTP 方法。

<CORS continueOnError="false" enabled="true" name="add-cors">
  <AllowOrigins>{request.header.origin}</AllowOrigins>
  <AllowMethods>GET, PUT, POST, DELETE</AllowMethods>
</CORS>

示例:
通配符

此示例指定允许所有 HTTP 方法访问资源。

<CORS continueOnError="false" enabled="true" name="add-cors">
  <AllowOrigins>{request.header.origin}</AllowOrigins>
  <AllowMethods>*</AllowMethods>
</CORS>

<AllowOrigins>

允许访问资源的来源列表。使用星号 (*) 可允许任何来源对资源进行访问。否则,请提供以英文逗号分隔的来源许可名单。如果找到匹配项,则传出 Access-Control-Allow-Origin 将被设置为客户端提供的来源。

默认值 不适用
是否必需? 必需
类型 字符串(支持消息模板*)
父元素 <CORS>
子元素

*如需了解详情,请参阅什么是消息模板?

<AllowOrigins> 元素使用以下语法:

语法

<CORS continueOnError="[false|true]" enabled="[false|true]" name="POLICY_NAME">
  <AllowOrigins>[{message template}|URL|URL, URL, ...|{context-variable}|{flow-variable}|*]</AllowOrigins>
</CORS>

示例:
单个网址

此示例指定允许访问资源的单个网址源。

<CORS continueOnError="false" enabled="true" name="add-cors">
  <AllowOrigins>https://www.w3.org</AllowOrigins>
</CORS>

示例:
多个网址

此示例指定允许访问资源的多个来源。

<CORS continueOnError="false" enabled="true" name="add-cors">
  <AllowOrigins>https://www.w3.org, https://www.apache.org</AllowOrigins>
</CORS>

示例:
上下文变量

此示例指定一个上下文变量,该变量表示允许访问资源的一个或多个来源。

<CORS continueOnError="false" enabled="true" name="add-cors">
  <AllowOrigins>{origins.list}</AllowOrigins>
</CORS>

示例:
流变量

此示例指定一个流变量,该变量表示允许访问资源的一个源。

<CORS continueOnError="false" enabled="true" name="add-cors">
  <AllowOrigins>{request.header.origin}</AllowOrigins>
</CORS>

示例:
通配符

此示例指定允许所有来源访问资源。

<CORS continueOnError="false" enabled="true" name="add-cors">
  <AllowOrigins>*</AllowOrigins>
</CORS>

<DisplayName>

除了用于 name 属性之外,还可用于在管理界面代理编辑器中使用其他更加自然的名称标记政策。

<DisplayName> 元素适用于所有政策。

默认值 不适用
是否必需? 可选。如果省略 <DisplayName>,则会使用政策的 name 属性的值
类型 字符串
父元素 <PolicyElement>
子元素

<DisplayName> 元素使用以下语法:

语法

<PolicyElement>
  <DisplayName>POLICY_DISPLAY_NAME</DisplayName>
  ...
</PolicyElement>

示例

<PolicyElement>
  <DisplayName>My Validation Policy</DisplayName>
</PolicyElement>

<DisplayName> 元素没有属性或子元素。

<ExposeHeaders>

允许浏览器访问的 HTTP 标头列表;或星号 (*),即允许访问所有 HTTP 标头。序列化Access-Control-Expose-Headers 标头。

默认值 如果未指定该项,则不会设置 Access-Control-Expose-Headers。 默认情况下,系统不会公开非简单标头。
是否必需? 可选
类型 字符串(支持消息模板*)
父元素 <CORS>
子元素

*如需了解详情,请参阅什么是消息模板?

<ExposeHeaders> 元素使用以下语法:

语法

<CORS continueOnError="[false|true]" enabled="[false|true]" name="POLICY_NAME">
  <AllowOrigins>[{message template}|URL|URL, URL, ...|{context-variable}|{flow-variable}|*]</AllowOrigins>
  <ExposeHeaders>[X-CUSTOM-HEADER-A, X-CUSTOM-HEADER-B, ... | *]</ExposeHeaders>
</CORS>

示例

此示例指定允许浏览器访问所有 HTTP 标头。

<CORS continueOnError="false" enabled="true" name="add-cors">
  <AllowOrigins>{request.header.origin}</AllowOrigins>
  <ExposeHeaders>*</ExposeHeaders>
</CORS>

<GeneratePreflightResponse>

指示政策是否应生成并返回 CORS 预检响应。如果为 false,则不会发送任何响应。在这种情况下,系统将填充以下流变量

  • cross_origin_resource_sharing.allow.credentials
  • cross_origin_resource_sharing.allow.headers
  • cross_origin_resource_sharing.allow.methods
  • cross_origin_resource_sharing.allow.origin
  • cross_origin_resource_sharing.allow.origins.list
  • cross_origin_resource_sharing.expose.headers
  • cross_origin_resource_sharing.max.age
  • cross_origin_resource_sharing.preflight.accepted
  • cross_origin_resource_sharing.request.headers
  • cross_origin_resource_sharing.request.method
  • cross_origin_resource_sharing.request.origin
  • cross_origin_resource_sharing.request.type
默认值 true
是否必需? 可选
类型 布尔值
父元素 <CORS>
子元素

<GeneratePreflightResponse> 元素使用以下语法:

语法

<CORS continueOnError="[false|true]" enabled="[false|true]" name="POLICY_NAME">
  <GeneratePreflightResponse>[false|true]</GeneratePreflightResponse>
  <GeneratePreflightResponse>[false|true]</GeneratePreflightResponse>
</CORS>

示例

此示例指定政策应生成并返回 CORS 预检响应。

<CORS continueOnError="false" enabled="true" name="add-cors">
  <AllowOrigins>{request.header.origin}</AllowOrigins>
  <GeneratePreflightResponse>true</GeneratePreflightResponse>
</CORS>

<IgnoreUnresolvedVariables>

确定在遇到无法解析的变量时处理是否停止。 设置为 true 可忽略无法解析的变量并继续处理;否则设置为 false

默认值 true
是否必需? 可选
类型 布尔值
父元素 <CORS>
子元素

<IgnoreUnresolvedVariables> 元素使用以下语法:

语法

<CORS continueOnError="[false|true]" enabled="[false|true]" name="POLICY_NAME">
  <AllowOrigins>[{message template}|URL|URL, URL, ...|{context-variable}|{flow-variable}|*]</AllowOrigins>
  <IgnoreUnresolvedVariables>[false|true]</IgnoreUnresolvedVariables>
</CORS>

示例

此示例指定在遇到未解析的变量时继续处理。

<CORS continueOnError="false" enabled="true" name="add-cors">
  <AllowOrigins>{request.header.origin}</AllowOrigins>
  <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
</CORS>

<MaxAge>

指定预检请求的结果可以缓存多长时间(以秒为单位)。值 -1 会将 Access-Control-Max-Age 标头填充为值 -1,这会停用缓存,并且需要对所有调用执行预检 OPTIONS 检查。此项在 Access-Control-Max-Age 规范中定义。

默认值 1800
是否必需? 可选
类型 整数
父元素 <CORS>
子元素

<MaxAge> 元素使用以下语法:

语法

<CORS continueOnError="[false|true]" enabled="[false|true]" name="POLICY_NAME">
  <AllowOrigins>[{message template}|URL|URL, URL, ...|{context-variable}|{flow-variable}|*]</AllowOrigins>
  <MaxAge>[integer|-1]</MaxAge>
</CORS>

示例:
缓存

此示例指定预检请求的结果可缓存 3628800 秒。

<CORS continueOnError="false" enabled="true" name="add-cors">
  <AllowOrigins>{request.header.origin}</AllowOrigins>
  <MaxAge>3628800</MaxAge>
</CORS>

示例:
无缓存

此示例指定无法缓存预检请求的结果。

<CORS continueOnError="false" enabled="true" name="add-cors">
  <AllowOrigins>{request.header.origin}</AllowOrigins>
  <MaxAge>-1</MaxAge>
</CORS>

使用说明

OPTIONS 请求

当 CORS 政策接收并处理 OPTIONS 请求时,代理流执行会完全跳过请求流,直接转移到代理响应 PreFlow,并从这里继续执行。无需创建条件来忽略代理请求流中的 OPTIONS 请求。

在后续调用中,当 CORS 政策执行时,如果政策中设置的 MaxAge 未过期,则流会照常运行。在“Response Sent to Client”之前的最终响应流中,特殊的 CORS 执行步骤“CORSResponseOrErrorFlowExecution”会设置 CORS 响应标头(Access-Control-Allow-CredentialsAccess-Control-Allow-OriginAccess-Control-Expose-Headers),以返回经过 CORS 验证的响应。

错误代码

本部分介绍当此政策触发错误时返回的故障代码和错误消息,以及由 Apigee 设置的故障变量。在开发故障规则以处理故障时,请务必了解此信息。如需了解详情,请参阅您需要了解的有关政策错误的信息处理故障

运行时错误

政策执行时可能会发生这些错误。

故障代码 HTTP 状态 原因
steps.cors.UnresolvedVariable 500 如果 CORS 政策中指定的变量为以下任一情况,就会出现此错误:
  • 超出范围(在执行政策的特定流中不可用)
  • 无法解析(未定义)

部署错误

在您部署包含此政策的代理时,可能会发生这些错误。

错误名称 原因
InvalidMaxAge MaxAge 不是数字
MissingAllowOrigins 未指定 AllowOrigins
InvalidHTTPMethods AllowMethods 中的某个方法无效
AllowHeadersSizeTooLarge AllowHeaders 中的字符串大小过大。
ExposeHeadersSizeTooLarge ExposeHeaders 中的字符串大小过大。

故障变量

当此政策在运行时触发错误时,将设置这些变量。如需了解详情,请参阅您需要了解的有关政策错误的信息

变量 其中 示例
fault.name = "FAULT_NAME" FAULT_NAME 是故障名称,如上面的运行时错误表中所列。故障名称是故障代码的最后一部分。 fault.name Matches "UnresolveVariable"
cors.POLICY_NAME.failed POLICY_NAME 是抛出故障的政策的用户指定名称。 cors.AddCORS.failed = true

错误响应示例

{
   "fault":{
      "detail":{
         "errorcode":"steps.cors.UnresolvedVariable"
      },
      "faultstring":"CORS[AddCORS]: unable to resolve variable wrong.var"
   }
}

故障规则示例

<FaultRule name="Add CORS Fault">
    <Step>
        <Name>Add-CORSCustomUnresolvedVariableErrorResponse</Name>
        <Condition>(fault.name Matches "UnresolvedVariable") </Condition>
    </Step>
    <Condition>(cors.Add-CORS.failed = true) </Condition>
</FaultRule>

流变量

系统将添加 CorsFlowInfo FlowInfo 对象,并且可以跟踪该对象。

属性 类型 读写 说明 范围开始
cross_origin_resource_sharing.allow.credentials 布尔值 读写 来自 <AllowCredentials> 的值 代理请求
cross_origin_resource_sharing.allow.headers 字符串 读写 来自 <AllowHeaders> 的值 代理请求
cross_origin_resource_sharing.allow.methods 字符串 读写 来自 <AllowMethods> 的值 代理请求
cross_origin_resource_sharing.allow.origin 字符串 读写 允许的请求来源;如果不在许可名单中,则为空 代理请求
cross_origin_resource_sharing.allow.origins.list 字符串 读写 来自 <AllowOrigins> 的值 代理请求
cross_origin_resource_sharing.expose.headers 字符串 读写 来自 <ExposeHeaders> 的值 代理请求
cross_origin_resource_sharing.max.age 整数 读写 来自 <MaxAge> 的值 代理请求
cross_origin_resource_sharing.preflight.accepted 布尔值 读写 指示是否接受预检请求 代理请求
cross_origin_resource_sharing.request.headers 字符串 读写 请求 Access-Control-Request-Headers 标头的值 代理请求
cross_origin_resource_sharing.request.method 字符串 读写 请求 Access-Control-Request-Method 标头的值 代理请求
cross_origin_resource_sharing.request.origin 字符串 读写 request.header.origin 相同 代理请求
cross_origin_resource_sharing.request.type 字符串 读写

CORS 请求的类型。可能的值:

  • ACTUAL:不属于预检请求的请求
  • PRE_FLIGHT::预检请求
代理请求