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>
      

示例

This example sets the Access-Control-Allow-Credentials header to false. That is, the caller is not allowed to send the actual request (not the preflight) using credentials.

<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 example

This example specifies the HTTP headers that can be used when requesting the resource.

<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>

示例:
列表

This example specifies the HTTP methods that are allowed to access the resource.

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

示例:
通配符

This example specifies that all HTTP methods are allowed to access the resource.

<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>

示例:
单个网址

This example specifies a single URL origin that is allowed to access the resource.

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

示例:
多个网址

This example specifies multiple origins that are allowed to access the resource.

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

示例:
上下文变量

This example specifies a context variable that represents one or more origins that are allowed to access the resource.

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

示例:
流变量

This example specifies a flow variable that represents one origin that is allowed to access the resource.

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

示例:
通配符

This example specifies that all origins are allowed to access the resource.

<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>

示例

This example specifies that the browsers are allowed to access all HTTP headers.

<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>

示例

This example specifies that the policy should generate and return the CORS preflight response.

<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>

示例

This example specifies that processing continues when an unresolved variable is encountered.

<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>

示例:
缓存

This example specifies that the results of a preflight request can be cached for 3628800 seconds.

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

示例:
无缓存

This example specifies that the results of a preflight request cannot be cached.

<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 验证的响应。

错误代码

This section describes the fault codes and error messages that are returned and fault variables that are set by Apigee when this policy triggers an error. This information is important to know if you are developing fault rules to handle faults. To learn more, see What you need to know about policy errors and Handling faults.

Runtime errors

These errors can occur when the policy executes.

Fault code HTTP status Cause
steps.cors.UnresolvedVariable 500 This error occurs if a variable specified in the CORS policy is either:
  • Out of scope (not available in the specific flow where the policy is being executed)
  • or

  • Can't be resolved (is not defined)

Deployment errors

These errors can occur when you deploy a proxy containing this policy.

Error name Cause
InvalidMaxAge MaxAge is not number
MissingAllowOrigins AllowOrigins is not specified
InvalidHTTPMethods One of the methods in AllowMethods is not valid
AllowHeadersSizeTooLarge The string size in AllowHeaders is too large.
ExposeHeadersSizeTooLarge The string size in ExposeHeaders is too large.

Fault variables

These variables are set when this policy triggers an error at runtime. For more information, see What you need to know about policy errors.

Variables Where Example
fault.name = "FAULT_NAME" FAULT_NAME is the name of the fault, as listed in the Runtime errors table above. The fault name is the last part of the fault code. fault.name Matches "UnresolveVariable"
cors.POLICY_NAME.failed POLICY_NAME is the user-specified name of the policy that threw the fault. cors.AddCORS.failed = true

Example error response

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

Example fault rule

<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::预检请求
代理请求