Вы просматриваете документацию по Apigee Edge.
Перейдите к документации по Apigee X. Информация
CORS (совместное использование ресурсов между разными источниками) – это стандартный механизм, который позволяет вызовам JavaScript XMLHttpRequest (XHR), выполняемым на веб-странице, взаимодействовать с ресурсами из доменов, отличных от источника. CORS – это распространенное решение, позволяющее обойти правило одинакового происхождения, которое действует во всех браузерах. Например, если вы выполните вызов XHR к Twitter API из кода JavaScript, выполняемого в браузере, вызов завершится неудачно. Это связано с тем, что домен, с которого страница загружается в ваш браузер, отличается от домена, с которого загружается Twitter API. CORS позволяет серверам разрешать совместное использование ресурсов между разными источниками.
Видео. Посмотрите короткое видео о том, как включить технологию CORS в прокси-сервере API.
Типичный вариант использования CORS
В следующем коде JQuery вызывается фиктивный целевой сервис. Если выполнить вызов из контекста браузера (веб-страницы), он завершится неудачно из-за правила ограничения домена:
<script> var url = "http://service.example.com"; $(document).ready(function(){ $("button").click(function(){ $.ajax({ type:"GET", url:url, async:true, dataType: "json", success: function(json) { // Parse the response. // Do other things. }, error: function(xhr, status, err) { // This is where we end up! } }); }); }); </script>
Одно из возможных решений этой проблемы – создать прокси-сервер API Apigee, который вызывает API сервиса на внутреннем сервере. Помните, что Edge находится между клиентом (в данном случае браузером) и серверным API (сервисом). Поскольку прокси-сервер API выполняется на сервере, а не в браузере, он может успешно вызвать сервис. Затем вам нужно будет только добавить заголовки CORS в ответ TargetEndpoint. Если браузер поддерживает CORS, эти заголовки сообщают ему, что можно "ослабить" правила ограничения домена и разрешить междоменный вызов API.
После создания прокси-сервера с поддержкой CORS вы можете вызывать URL прокси API вместо сервиса на стороне сервера в коде на стороне клиента. Пример:
<script> var url = "http://myorg-test.apigee.net/v1/example"; $(document).ready(function(){ $("button").click(function(){ $.ajax({ type:"GET", url:url, async:true, dataType: "json", success: function(json) { // Parse the response. // Do other things. }, error: function(xhr, status, err) { // This time, we do not end up here! } }); }); }); </script>
Как прикрепить политику CORS к новому прокси API
Вы можете добавить поддержку технологии CORS в прокси-сервер API, прикрепив к нему правило "Добавить CORS" при создании. Чтобы добавить это правило, установите флажок Добавить заголовки CORS на странице "Безопасность" мастера создания прокси.
Если вы установите этот флажок, в систему будет автоматически добавлено правило Add CORS и прикреплено к предварительному потоку ответов TargetEndpoint, как показано на рисунке ниже.

Правило Add CORS реализовано как правило AssignMessage, которое добавляет в ответ нужные заголовки. По сути, заголовки сообщают браузеру, с какими источниками он будет обмениваться ресурсами, какие методы он принимает и т. д. Подробнее об этих заголовках CORS можно узнать в рекомендациях W3C по совместному использованию ресурсов между разными источниками.
Вам необходимо изменить правила следующим образом:
- Добавьте заголовки
content-typeиauthorization(необходимые для поддержки базовой аутентификации или OAuth2) в заголовокAccess-Control-Allow-Headers, как показано в фрагменте кода ниже. - При аутентификации OAuth2 может потребоваться исправить несоответствие RFC.
- Рекомендуем использовать для настройки заголовков CORS метод
<Set>, а не<Add>, как показано в приведенном ниже фрагменте кода. Если при использовании<Add>заголовокAccess-Control-Allow-Originуже существует, вы получите следующее сообщение об ошибке:The 'Access-Control-Allow-Origin' header contains multiple values '*, *', but only one is allowed.Подробнее об ошибке CORS : заголовок содержит несколько значений "*, *", но разрешено только одно…
<AssignMessage async="false" continueOnError="false" enabled="true" name="add-cors"> <DisplayName>Add CORS</DisplayName> <FaultRules/> <Properties/> <Set> <Headers> <Header name="Access-Control-Allow-Origin">{request.header.origin}</Header> <Header name="Access-Control-Allow-Headers">origin, x-requested-with, accept, content-type, authorization</Header> <Header name="Access-Control-Max-Age">3628800</Header> <Header name="Access-Control-Allow-Methods">GET, PUT, POST, DELETE</Header> </Headers> </Set> <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables> <AssignTo createNew="false" transport="http" type="response"/> </AssignMessage>
Как добавить заголовки CORS в существующий прокси-сервер
Вам нужно вручную создать новую политику Assign Message и скопировать в нее код для политики Add CORS, указанный в предыдущем разделе. Затем прикрепите правило к предварительному потоку ответов TargetEndpoint прокси-сервера API. При необходимости вы можете изменить значения заголовков. Подробнее о том, что такое правила…
Обработка предварительных запросов CORS
Предварительный запрос CORS – это запрос, отправляемый на сервер, чтобы проверить, поддерживает ли он CORS. Типичные ответы на предварительные запросы содержат информацию о том, какие источники будет принимать сервер для запросов CORS, список HTTP-методов, поддерживаемых для запросов CORS, заголовки, которые можно использовать как часть запроса ресурса, максимальное время, в течение которого будет кешироваться ответ на предварительный запрос, и т. д. Если сервис не поддерживает CORS или не хочет принимать междоменные запросы от источника клиента, будет применено междоменное правило браузера, и все междоменные запросы, отправленные клиентом для взаимодействия с ресурсами, размещенными на этом сервере, будут отклонены.
Как правило, предварительные запросы CORS выполняются с помощью метода HTTP OPTIONS. Когда сервер, поддерживающий CORS, получает запрос OPTIONS, он возвращает клиенту набор заголовков CORS, указывающих на уровень поддержки CORS. В результате этого обмена данными клиент узнает, что он может запросить у домена, не являющегося исходным.
Подробнее о предварительных запросах… Кроме того, в интернете можно найти множество статей и блогов, посвященных CORS.
Apigee не включает готовое решение для предварительных запросов CORS, но его можно реализовать, как описано в этом разделе. Цель – чтобы прокси-сервер оценил запрос OPTIONS в условном потоке. После этого прокси-сервер может отправить клиенту подходящий ответ.
Ниже приведен пример рабочего процесса, а затем описаны его части, которые обрабатывают запрос на предварительную проверку:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ProxyEndpoint name="default">
<Description/>
<Flows>
<Flow name="OptionsPreFlight">
<Request/>
<Response>
<Step>
<Name>add-cors</Name>
</Step>
</Response>
<Condition>request.verb == "OPTIONS" AND request.header.origin != null AND request.header.Access-Control-Request-Method != null</Condition>
</Flow>
</Flows>
<PreFlow name="PreFlow">
<Request/>
<Response/>
</PreFlow>
<HTTPProxyConnection>
<BasePath>/v1/cnc</BasePath>
<VirtualHost>default</VirtualHost>
<VirtualHost>secure</VirtualHost>
</HTTPProxyConnection>
<RouteRule name="NoRoute">
<Condition>request.verb == "OPTIONS" AND request.header.origin != null AND request.header.Access-Control-Request-Method != null</Condition>
</RouteRule>
<RouteRule name="default">
<TargetEndpoint>default</TargetEndpoint>
</RouteRule>
<PostFlow name="PostFlow">
<Request/>
<Response/>
</PostFlow>
</ProxyEndpoint>Основные части этого ProxyEndpoint:
- Для запроса OPTIONS создается правило RouteRule с целевым значением NULL. Обратите внимание, что TargetEndpoint не указан. Если получен запрос OPTIONS и заголовки запроса Origin и Access-Control-Request-Method не являются нулевыми, прокси-сервер немедленно возвращает заголовки CORS в ответе клиенту (минуя фактическую целевую точку по умолчанию).
Подробнее об условиях потока и правилах маршрутизации…
<RouteRule name="NoRoute"> <Condition>request.verb == "OPTIONS" AND request.header.origin != null AND request.header.Access-Control-Request-Method != null</Condition> </RouteRule> - Создается поток OptionsPreFlight, который добавляет в поток правило Add CORS, содержащее заголовки CORS, если получен запрос OPTIONS и заголовки запроса Origin и Access-Control-Request-Method не являются нулевыми.
<Flow name="OptionsPreFlight"> <Request/> <Response> <Step> <Name>add-cors</Name> </Step> </Response> <Condition>request.verb == "OPTIONS" AND request.header.origin != null AND request.header.Access-Control-Request-Method != null</Condition> </Flow>
Как использовать образец решения CORS
Пример решения CORS, реализованного в виде общего потока, доступен на GitHub. Импортируйте пакет общего потока в свою среду и подключите его с помощью хуков потока или непосредственно к потокам прокси-сервера API. Подробную информацию можно найти в файле CORS-Shared-FLow README, который поставляется с примером.