Esta página se aplica a Apigee y Apigee Hybrid.
Consulta la documentación de Apigee Edge.
Qué
El uso compartido de recursos entre dominios (CORS) es un mecanismo estándar que permite que las llamadas XMLHttpRequest (XHR) de JavaScript que se ejecutan en una página web interactúen con recursos de dominios que no son de origen, CORS es una solución implementada con frecuencia en la política del mismo origen que aplican todos los navegadores.
Por ejemplo, si realizas una llamada XHR a la API de Twitter desde el código JavaScript que se ejecuta en el navegador, la llamada fallará. Esto se debe a que el dominio que entrega la página a tu navegador no es el mismo dominio que entrega la API de Twitter. CORS proporciona una solución a este problema, ya que permite que los servidores lo habiliten si desean proporcionar uso compartido de recursos entre dominios.
Esta política de CORS permite a los clientes de Apigee establecer políticas de CORS para las APIs consumidas por las aplicaciones web.
Esta es una política estándar y se puede implementar en cualquier tipo de entorno. Para obtener información sobre los tipos de políticas y la disponibilidad con cada tipo de entorno, consulta Tipos de políticas.
Elemento <CORS>
Define la política de CORS.
Valor predeterminado | Consulta la pestaña Política predeterminada, a continuación |
¿Es obligatorio? | Obligatorio |
Tipo | Objeto complejo |
Elemento principal | N/A |
Elementos secundarios |
<AllowCredentials> <AllowHeaders> <AllowMethods> <AllowOrigins> <DisplayName> <ExposeHeaders> <GeneratePreflightResponse> <IgnoreUnresolvedVariables> <MaxAge> |
El elemento <CORS>
usa la siguiente sintaxis:
Sintaxis
El elemento <CORS>
usa la siguiente sintaxis:
<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>
Política predeterminada
En el siguiente ejemplo, se muestra la configuración predeterminada cuando agregas la política de CORS a tu flujo en la IU de Edge:
<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>
Cuando insertas una nueva política de CORS
en la IU de Apigee, la plantilla contiene stubs para todas las operaciones posibles. Por lo general, debes seleccionar qué operaciones quieres realizar con esta política y quitar el resto de los elementos secundarios. Por ejemplo, si deseas especificar los métodos HTTP permitidos para acceder al recurso, usa el elemento <AllowMethods>
y quita los otros elementos secundarios de la política para que sea más legible.
Este elemento tiene los siguientes atributos que son comunes a todas las políticas:
Atributo | Predeterminada | (obligatorio) | Descripción |
---|---|---|---|
name |
N/A | Obligatorio |
El nombre interno de la política. El valor del atributo De forma opcional, usa el elemento |
continueOnError |
falso | Opcional | Configúralo como false para mostrar un error cuando una política falla. Este es el comportamiento previsto para la mayoría de las políticas. Configúralo como true para continuar con la ejecución del flujo incluso después de que una política falle. También consulta:
|
enabled |
true | Opcional | Configúralo como true para aplicar la política. Configúralo como false para desactivar la política. La política no se aplicará, incluso si permanece conectada a un flujo. |
async |
falso | Obsoleta | Este atributo dejó de estar disponible. |
Cada uno de estos elementos secundarios se describe en las siguientes secciones.
Ejemplos
En las siguientes secciones, se proporcionan ejemplos de todos los elementos secundarios.
Referencia del elemento secundario
En esta sección, se describen los elementos secundarios de <CORS>
.
<AllowCredentials>
Indica si el emisor puede enviar la solicitud real (no la solicitud preliminar) mediante credenciales. Se traduce al encabezado Access-Control-Allow-Credentials
.
Valor predeterminado | Si no se especifica, no se establecerá Access-Control-Allow-Credentials . |
¿Es obligatorio? | Opcional |
Tipo | Booleano |
Elemento principal |
<CORS>
|
Elementos secundarios | Ninguno |
El elemento <AllowCredentials>
usa la siguiente sintaxis:
Sintaxis
<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>
Ejemplo
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>
Lista de los encabezados HTTP que se pueden usar cuando se solicita el recurso.
Serializado en el encabezado Access-Control-Allow-Headers
.
Valor predeterminado | Origin, Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers |
¿Es obligatorio? | Opcional |
Tipo | String, con plantilla de mensaje* compatible |
Elemento principal |
<CORS>
|
Elementos secundarios | Ninguno |
* Para obtener más información, consulta ¿Qué es una plantilla de mensaje?
El elemento <AllowHeaders>
usa la siguiente sintaxis:
Sintaxis
<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>
Ejemplo
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>
Lista de los métodos HTTP permitidos para acceder al recurso. El contenido se serializará en el encabezado Access-Control-Allow-Methods
.
Valor predeterminado | GET, POST, HEAD, OPTIONS |
¿Es obligatorio? | Opcional |
Tipo | String, con plantilla de mensaje* compatible |
Elemento principal |
<CORS>
|
Elementos secundarios | Ninguno |
* Para obtener más información, consulta ¿Qué es una plantilla de mensaje?
El elemento <AllowMethods>
usa la siguiente sintaxis:
Sintaxis
<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>
Ejemplo:
Lista
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>
Ejemplo:
Comodín
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>
Una lista de orígenes que tienen acceso al recurso. Usa un asterisco (*
) para habilitar el acceso a un recurso desde cualquier origen. De lo contrario, proporciona una lista de orígenes permitidos separados por comas. Si se encuentra una coincidencia, el Access-Control-Allow-Origin
saliente se configura en el origen según lo que proporciona el cliente.
Valor predeterminado | N/A |
¿Es obligatorio? | Obligatorio |
Tipo | String, con plantilla de mensaje* compatible |
Elemento principal |
<CORS>
|
Elementos secundarios | Ninguno |
* Para obtener más información, consulta ¿Qué es una plantilla de mensaje?
El elemento <AllowOrigins>
usa la siguiente sintaxis:
Sintaxis
<CORS continueOnError="[false|true]" enabled="[false|true]" name="POLICY_NAME"> <AllowOrigins>[{message template}|URL|URL, URL, ...|{context-variable}|{flow-variable}|*]</AllowOrigins> </CORS>
Ejemplo:
URL única
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>
Ejemplo:
Varias URL
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>
Ejemplo:
Variable de contexto
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>
Ejemplo:
Variable de flujo
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>
Ejemplo:
Comodín
En este ejemplo, se especifica que todos los orígenes pueden acceder al recurso.
<CORS continueOnError="false" enabled="true" name="add-cors"> <AllowOrigins>*</AllowOrigins> </CORS>
<DisplayName>
Se usan además del atributo name
para etiquetar la política en el editor de proxy de la IU de administración con un nombre de lenguaje natural diferente.
El elemento <DisplayName>
es común a todas las políticas.
Valor predeterminado | N/A |
¿Es obligatorio? | Opcional. Si omites <DisplayName> , se usa el valor del atributo name de la política. |
Tipo | String |
Elemento principal | <PolicyElement> |
Elementos secundarios | Ninguno |
El elemento <DisplayName>
usa la siguiente sintaxis:
Sintaxis
<PolicyElement> <DisplayName>POLICY_DISPLAY_NAME</DisplayName> ... </PolicyElement>
Ejemplo
<PolicyElement> <DisplayName>My Validation Policy</DisplayName> </PolicyElement>
El elemento <DisplayName>
no tiene atributos ni elementos secundarios.
<ExposeHeaders>
Una lista de encabezados HTTP a los que los navegadores pueden acceder o un asterisco (*
) para permitir todos los encabezados HTTP.
Serializado en el encabezado Access-Control-Expose-Headers
.
Valor predeterminado | Si no se especifica, no se establecerá Access-Control-Expose-Headers . Los encabezados no simples no se exponen de forma predeterminada. |
¿Es obligatorio? | Opcional |
Tipo | String, con plantilla de mensaje* compatible |
Elemento principal |
<CORS>
|
Elementos secundarios | Ninguno |
* Para obtener más información, consulta ¿Qué es una plantilla de mensaje?
El elemento <ExposeHeaders>
usa la siguiente sintaxis:
Sintaxis
<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>
Ejemplo
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>
Indica si la política debe generar y mostrar la respuesta de solicitud preliminar de CORS.
Si es false
, no se envía ninguna respuesta. En su lugar, se propagan las siguientes variables de flujo:
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
Valor predeterminado | true |
¿Es obligatorio? | Opcional |
Tipo | Booleano |
Elemento principal |
<CORS>
|
Elementos secundarios | Ninguno |
El elemento <GeneratePreflightResponse>
usa la siguiente sintaxis:
Sintaxis
<CORS continueOnError="[false|true]" enabled="[false|true]" name="POLICY_NAME"> <GeneratePreflightResponse>[false|true]</GeneratePreflightResponse> <GeneratePreflightResponse>[false|true]</GeneratePreflightResponse> </CORS>
Ejemplo
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>
Determina si el procesamiento se detiene cuando se encuentra una variable sin resolver.
Configúralo como true
para ignorar las variables sin resolver y continuar con el procesamiento, de lo contrario, false
.
Valor predeterminado | true |
¿Es obligatorio? | Opcional |
Tipo | Booleano |
Elemento principal |
<CORS>
|
Elementos secundarios | Ninguno |
El elemento <IgnoreUnresolvedVariables>
usa la siguiente sintaxis:
Sintaxis
<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>
Ejemplo
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>
Especifica cuánto tiempo se pueden almacenar en caché los resultados de una solicitud preliminar en segundos.
Un valor de -1
propaga el encabezado Access-Control-Max-Age
con un valor de -1
, que inhabilita el almacenamiento en caché, lo que requiere una verificación de solicitud preliminar
OPTIONS
para todas las llamadas. Esto se define en la especificación
Access-Control-Max-Age
.
Valor predeterminado | 1800 |
¿Es obligatorio? | Opcional |
Tipo | Entero |
Elemento principal |
<CORS>
|
Elementos secundarios | Ninguno |
El elemento <MaxAge>
usa la siguiente sintaxis:
Sintaxis
<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>
Ejemplo:
Caché
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>
Ejemplo:
Sin caché
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>
Notas de uso
Solicitudes OPTIONS
Cuando se recibe y procesa una solicitud OPTIONS
mediante la política de CORS, la ejecución del flujo del proxy se transfiere directamente al flujo previo de respuesta del proxy. Se omite el flujo de solicitud por completo y continúa la ejecución desde allí. No es necesario crear una condición para ignorar la solicitud de OPTIONS en el flujo de solicitud de proxy.
En las llamadas posteriores, cuando la política de CORS se ejecuta, si el MaxAge
establecido en la política no venció, el flujo continúa con normalidad. Durante el flujo de respuesta final justo antes de “Respuesta enviada al cliente”, un paso de ejecución especial de CORS “CORSResponseOrErrorFlowExecution” establece encabezados de respuesta CORS (Access-Control-Allow-Credentials
, Access-Control-Allow-Origin
y Access-Control-Expose-Headers
) para mostrar una respuesta validada por CORS.
Códigos de error
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:
or |
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>
Variables de flujo
Se agregará el objeto CorsFlowInfo
FlowInfo
y estará disponible para realizar un seguimiento.
Propiedad | Tipo | Lectura/escritura | Descripción | El permiso comienza |
---|---|---|---|---|
cross_origin_resource_sharing.allow.credentials |
Booleano | Lectura/escritura | Valor desde <AllowCredentials> |
Solicitud de proxy |
cross_origin_resource_sharing.allow.headers |
String | Lectura/escritura | Valor desde <AllowHeaders> |
Solicitud de proxy |
cross_origin_resource_sharing.allow.methods |
String | Lectura/escritura | Valor desde <AllowMethods> |
Solicitud de proxy |
cross_origin_resource_sharing.allow.origin |
String | Lectura/escritura | El origen de la solicitud permitido; vacío si no está en la lista de anunciantes permitidos | Solicitud de proxy |
cross_origin_resource_sharing.allow.origins.list |
String | Lectura/escritura | Valor desde <AllowOrigins> |
Solicitud de proxy |
cross_origin_resource_sharing.expose.headers |
String | Lectura/escritura | Valor desde <ExposeHeaders> |
Solicitud de proxy |
cross_origin_resource_sharing.max.age |
Número entero | Lectura/escritura | Valor desde <MaxAge> |
Solicitud de proxy |
cross_origin_resource_sharing.preflight.accepted |
Booleano | Lectura/escritura | Indica si se acepta la solicitud preliminar | Solicitud de proxy |
cross_origin_resource_sharing.request.headers |
String | Lectura/escritura | El valor del encabezado Access-Control-Request-Headers de la solicitud |
Solicitud de proxy |
cross_origin_resource_sharing.request.method |
String | Lectura/escritura | El valor del encabezado Access-Control-Request-Method de la solicitud |
Solicitud de proxy |
cross_origin_resource_sharing.request.origin |
String | Lectura/escritura | Es igual a request.header.origin |
Solicitud de proxy |
cross_origin_resource_sharing.request.type |
String | Lectura/escritura |
Tipo de solicitud de CORS. Valores posibles:
|
Solicitud de proxy |