CORS
Межсайтовый обмен ресурсами (CORS)
Базовая поддержка Широко доступно
Эта функция хорошо зарекомендовала себя и работает на многих устройствах и в различных версиях браузеров. Она доступна в браузерах с июля 2015 года.
Межсайтовый обмен ресурсами (CORS) — это механизм на основе HTTP-заголовков, который позволяет серверу указывать любые источники (домен, схему или порт), отличные от его собственного, с которых браузеру разрешено загружать ресурсы. CORS также использует механизм, с помощью которого браузеры отправляют серверу, на котором размещён межсайтовый ресурс, предварительный запрос, чтобы проверить, разрешит ли сервер фактический запрос. В таком предварительном запросе браузер отправляет заголовки, указывающие HTTP-метод и заголовки, которые будут использоваться в фактическом запросе.
Пример межсайтового запроса: код JavaScript на стороне клиента, предоставленный с https://domain-a.com, использует fetch() для запроса https://domain-b.com/data.json.
По соображениям безопасности браузеры ограничивают межсайтовые HTTP-запросы, инициированные скриптами. Например, fetch() и XMLHttpRequest подчиняются политике одного источника. Это означает, что веб-приложение, использующее эти API, может запрашивать ресурсы только из того же источника, откуда было загружено приложение, если только ответ с других источников не содержит нужные заголовки CORS.
Механизм CORS поддерживает безопасные межсайтовые запросы и передачу данных между браузерами и серверами. Браузеры используют CORS в таких API, как fetch() или XMLHttpRequest, чтобы снизить риски, связанные с межсайтовыми HTTP-запросами.
Для каких запросов используется CORS?
Этот стандарт межсайтового обмена позволяет выполнять межсайтовые HTTP-запросы для:
- Вызовов
fetch()илиXMLHttpRequest, как описано выше. - Веб-шрифтов (для междоменного использования шрифтов в
@font-faceв CSS), как описано в требованиях к загрузке шрифтов, чтобы серверы могли размещать шрифты TrueType, которые можно загружать только из другого источника и использовать на веб-сайтах, которым это разрешено. - Текстур WebGL.
- Изображений и видеокадров, рисуемых на холсте с помощью
drawImage(). - CSS-фигур, созданных из изображений.
В этой общей статье о межсайтовом обмене ресурсами также рассматриваются необходимые HTTP-заголовки.
Обзор принципа работы
Стандарт межсайтового обмена ресурсами работает за счёт добавления новых HTTP-заголовков, с помощью которых серверы сообщают, каким источникам разрешено читать эту информацию из веб-браузера. Кроме того, для методов HTTP-запросов, способных вызвать побочные эффекты при работе с данными сервера (в частности, для методов HTTP, отличных от GET, или POST с определёнными типами MIME), спецификация требует, чтобы браузеры предварительно проверяли запрос: отправляли серверу запрос с методом HTTP OPTIONS, чтобы узнать, какие методы он поддерживает, а затем, получив от сервера «разрешение», отправляли фактический запрос. Серверы также могут сообщать клиентам, следует ли отправлять вместе с запросами «учётные данные» (например, файлы cookie и данные HTTP-аутентификации).
Сбои CORS приводят к ошибкам, однако по соображениям безопасности подробности об ошибке недоступны JavaScript. Код знает только о том, что произошла ошибка. Единственный способ выяснить, что именно пошло не так, — посмотреть подробности в консоли браузера.
В следующих разделах рассматриваются сценарии использования и приводится описание используемых HTTP-заголовков.
Примеры сценариев управления доступом
Рассмотрим три сценария, демонстрирующих принцип работы межсайтового обмена ресурсами. Во всех примерах используется fetch(), с помощью которого можно выполнять межсайтовые запросы в любом браузере, поддерживающем эту функцию.
Простые запросы
Некоторые запросы не запускают предварительную проверку CORS. В устаревшей спецификации CORS их называли простыми запросами, хотя в спецификации Fetch (которая теперь определяет CORS) этот термин не используется.
Причина в том, что элемент <form> из HTML 4.0 (появившийся до межсайтовых fetch() и XMLHttpRequest) может отправлять простые запросы к любому источнику. Поэтому любой разработчик сервера уже должен защищаться от межсайтовой подделки запросов (CSRF). Исходя из этого предположения, серверу не нужно давать согласие (отвечая на предварительный запрос) на получение запросов, похожих на отправку формы, поскольку угроза CSRF не выше, чем при отправке формы. Однако серверу всё равно нужно дать согласие с помощью Access-Control-Allow-Origin, чтобы предоставить ответ скрипту.
Простой запрос — это запрос, который удовлетворяет всем следующим условиям:
-
Используется один из разрешённых методов:
-
Помимо заголовков, автоматически устанавливаемых пользовательским агентом (например,
Connection,User-Agentили запрещённых заголовков запросов), вручную можно задавать только заголовки запросов, входящие в список разрешённых CORS:AcceptAccept-LanguageContent-Language-
Content-Type(обратите внимание на дополнительные требования ниже) -
Range(только с единственным значением заголовка диапазона, напримерbytes=256-илиbytes=127-255)
-
Для типа мультимедиа, указанного в заголовке
Content-Type, разрешены только следующие сочетания типа и подтипа:application/x-www-form-urlencodedmultipart/form-datatext/plain
-
Если запрос выполняется с помощью объекта
XMLHttpRequest, для объекта, возвращаемого свойствомXMLHttpRequest.upload, используемым в запросе, не регистрируются обработчики событий; то есть для экземпляраXMLHttpRequestxhrкод не вызывалxhr.upload.addEventListener()для добавления обработчика события, отслеживающего загрузку. -
В запросе не используется объект
ReadableStream.
Примечание: WebKit Nightly и Safari Technology Preview накладывают дополнительные ограничения на допустимые значения заголовков Accept, Accept-Language и Content-Language. Если в любом из этих заголовков указаны «нестандартные» значения, WebKit/Safari не считает запрос «простым». Значения, которые WebKit/Safari считает «нестандартными», не документированы, за исключением следующих ошибок WebKit:
- Требовать предварительную проверку для нестандартных заголовков запросов Accept, Accept-Language и Content-Language из списка разрешённых CORS
- Разрешить запятые в заголовках запросов Accept, Accept-Language и Content-Language для простого CORS
- Перейти к модели чёрного списка для ограниченных заголовков Accept в простых запросах CORS
Другие браузеры не применяют эти дополнительные ограничения, поскольку их нет в спецификации.
Например, предположим, что веб-контент на https://foo.example хочет получить JSON с домена https://bar.other. Для этого в JavaScript-коде, размещённом на foo.example, можно использовать следующий код:
const fetchPromise = fetch("https://bar.other");
fetchPromise
.then((response) => response.json())
.then((data) => {
console.log(data);
});
Эта операция выполняет простой обмен данными между клиентом и сервером, используя заголовки CORS для управления доступом:
Посмотрим, что браузер отправит серверу в этом случае:
GET /resources/public-data/ HTTP/1.1 Host: bar.other User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:71.0) Gecko/20100101 Firefox/71.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: en-us,en;q=0.5 Accept-Encoding: gzip,deflate Connection: keep-alive Origin: https://foo.example
Обратите внимание на заголовок запроса Origin, который показывает, что вызов поступает с https://foo.example.
Теперь посмотрим, как ответит сервер:
HTTP/1.1 200 OK Date: Mon, 01 Dec 2008 00:23:53 GMT Server: Apache/2 Access-Control-Allow-Origin: * Keep-Alive: timeout=2, max=100 Connection: Keep-Alive Transfer-Encoding: chunked Content-Type: application/xml […XML Data…]
В ответ сервер возвращает заголовок Access-Control-Allow-Origin со значением Access-Control-Allow-Origin: *, что означает, что доступ к ресурсу разрешён из любого источника.
Access-Control-Allow-Origin: *
Такая комбинация заголовков Origin и Access-Control-Allow-Origin — простейший вариант использования протокола управления доступом. Если бы владельцы ресурса на https://bar.other хотели разрешить доступ к ресурсу только для запросов с https://foo.example (то есть ни один домен, кроме https://foo.example, не мог бы получать доступ к ресурсу из другого источника), они отправили бы:
Access-Control-Allow-Origin: https://foo.example
Примечание: Отвечая на запрос с учётными данными, сервер должен указать источник в значении заголовка Access-Control-Allow-Origin, а не использовать подстановочный символ *.
Запросы с предварительной проверкой
В отличие от простых запросов, для запросов с предварительной проверкой браузер сначала отправляет HTTP-запрос методом OPTIONS к ресурсу на другом источнике, чтобы определить, безопасно ли отправлять фактический запрос. Такие межсайтовые запросы проходят предварительную проверку, поскольку могут повлиять на пользовательские данные.
Ниже приведён пример запроса, который проходит предварительную проверку:
const fetchPromise = fetch("https://bar.other/doc", {
method: "POST",
mode: "cors",
headers: {
"Content-Type": "text/xml",
"X-PINGOTHER": "pingpong",
},
body: "<person><name>Arun</name></person>",
});
fetchPromise.then((response) => {
console.log(response.status);
});
В приведённом выше примере создаётся XML-тело для отправки с запросом POST. Кроме того, задаётся нестандартный HTTP-заголовок запроса X-PINGOTHER. Такие заголовки не входят в HTTP/1.1, но обычно полезны веб-приложениям. Поскольку запрос использует Content-Type со значением text/xml и в нём задан пользовательский заголовок, для него выполняется предварительная проверка.
Примечание: Как описано ниже, фактический запрос POST не содержит заголовки Access-Control-Request-*; они нужны только для запроса OPTIONS.
Рассмотрим полный обмен данными между клиентом и сервером. Сначала выполняется предварительный запрос и ответ на него:
OPTIONS /doc HTTP/1.1 Host: bar.other User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:71.0) Gecko/20100101 Firefox/71.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: en-us,en;q=0.5 Accept-Encoding: gzip,deflate Connection: keep-alive Origin: https://foo.example Access-Control-Request-Method: POST Access-Control-Request-Headers: content-type,x-pingother HTTP/1.1 204 No Content Date: Mon, 01 Dec 2008 01:15:39 GMT Server: Apache/2 Access-Control-Allow-Origin: https://foo.example Access-Control-Allow-Methods: POST, GET, OPTIONS Access-Control-Allow-Headers: X-PINGOTHER, Content-Type Access-Control-Max-Age: 86400 Vary: Accept-Encoding, Origin Keep-Alive: timeout=2, max=100 Connection: Keep-Alive
Первый блок выше представляет предварительный запрос с методом OPTIONS. Браузер определяет необходимость отправки этого запроса на основе параметров запроса, используемых в приведённом выше фрагменте JavaScript-кода, чтобы сервер мог сообщить, допустимо ли отправлять запрос с фактическими параметрами. OPTIONS — это метод HTTP/1.1, который используется для получения дополнительной информации от серверов. Он является безопасным, то есть его нельзя использовать для изменения ресурса. Вместе с запросом OPTIONS отправляются ещё два заголовка запроса:
Access-Control-Request-Method: POST Access-Control-Request-Headers: content-type,x-pingother
Заголовок Access-Control-Request-Method сообщает серверу в рамках предварительного запроса, что фактический запрос будет отправлен с методом POST. Заголовок Access-Control-Request-Headers сообщает серверу, что фактический запрос будет отправлен с пользовательскими заголовками X-PINGOTHER и Content-Type. Теперь сервер может определить, допустимо ли принять запрос при этих условиях.
Во втором блоке выше представлен ответ сервера, указывающий, что метод запроса (POST) и заголовки запроса (X-PINGOTHER) допустимы. Рассмотрим следующие строки подробнее:
Access-Control-Allow-Origin: https://foo.example Access-Control-Allow-Methods: POST, GET, OPTIONS Access-Control-Allow-Headers: X-PINGOTHER, Content-Type Access-Control-Max-Age: 86400
Сервер отвечает заголовком Access-Control-Allow-Origin: https://foo.example, ограничивая доступ только доменом источника, отправившего запрос. Он также отвечает заголовком Access-Control-Allow-Methods, который сообщает, что POST и GET — допустимые методы для обращения к этому ресурсу (этот заголовок похож на заголовок ответа Allow, но используется исключительно в контексте управления доступом).
Сервер также отправляет заголовок Access-Control-Allow-Headers со значением X-PINGOTHER, Content-Type, подтверждая, что эти заголовки разрешено использовать в фактическом запросе. Как и Access-Control-Allow-Methods, Access-Control-Allow-Headers представляет собой список допустимых заголовков, разделённых запятыми.
Наконец, Access-Control-Max-Age задаёт время в секундах, в течение которого можно кэшировать ответ на предварительный запрос, не отправляя новый предварительный запрос. Значение по умолчанию — 5 секунд. В данном случае максимальный срок составляет 86 400 секунд (= 24 часа). Обратите внимание, что в каждом браузере есть максимальное внутреннее значение, которое имеет приоритет, если Access-Control-Max-Age превышает его.
После завершения предварительной проверки отправляется фактический запрос:
POST /doc HTTP/1.1 Host: bar.other User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:71.0) Gecko/20100101 Firefox/71.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: en-us,en;q=0.5 Accept-Encoding: gzip,deflate Connection: keep-alive X-PINGOTHER: pingpong Content-Type: text/xml; charset=UTF-8 Referer: https://foo.example/examples/preflightInvocation.html Content-Length: 55 Origin: https://foo.example Pragma: no-cache Cache-Control: no-cache <person><name>Arun</name></person> HTTP/1.1 200 OK Date: Mon, 01 Dec 2008 01:15:40 GMT Server: Apache/2 Access-Control-Allow-Origin: https://foo.example Vary: Accept-Encoding, Origin Content-Encoding: gzip Content-Length: 235 Keep-Alive: timeout=2, max=99 Connection: Keep-Alive Content-Type: text/plain [Some XML content]
Запросы с предварительной проверкой и перенаправления
В настоящее время не все браузеры поддерживают переход по перенаправлениям после предварительной проверки запроса. Если после такого запроса происходит перенаправление, некоторые браузеры выдают сообщение об ошибке, например:
Запрос перенаправлен на
https://example.com/foo, что запрещено для межсайтовых запросов, требующих предварительной проверки. Запрос требует предварительной проверки, при которой запрещено переходить по межсайтовым перенаправлениям.
Изначально протокол CORS требовал такого поведения, но впоследствии это требование было отменено. Однако изменения реализованы не во всех браузерах, и некоторые из них по-прежнему ведут себя согласно исходному требованию.
Пока браузеры не приведут поведение в соответствие со спецификацией, можно попытаться обойти это ограничение одним из следующих способов или обоими сразу:
- Изменить поведение на стороне сервера, чтобы избежать предварительной проверки и/или перенаправления
- Изменить запрос так, чтобы он стал простым запросом, не требующим предварительной проверки
Если это невозможно, можно сделать следующее:
- Выполнить простой запрос (используя
Response.urlдля Fetch API илиXMLHttpRequest.responseURL), чтобы определить URL, на который в итоге будет перенаправлен фактический запрос с предварительной проверкой. - Выполнить ещё один запрос (фактический запрос), используя URL, полученный на первом шаге с помощью
Response.urlилиXMLHttpRequest.responseURL.
Однако если предварительная проверка запроса выполняется из-за наличия в запросе заголовка Authorization, обойти это ограничение описанными выше способами не удастся. Кроме того, обойти его вообще невозможно, если у вас нет контроля над сервером, к которому отправляется запрос.
Запросы с учётными данными
Примечание: При отправке запросов с учётными данными на другой домен по-прежнему действуют правила использования сторонних файлов cookie. Эти правила применяются всегда, независимо от настроек сервера и клиента, описанных в этой главе.
Наиболее интересная возможность, доступная как в fetch() и XMLHttpRequest, так и в CORS, — отправлять запросы с учётными данными, учитывающие HTTP-файлы cookie и данные HTTP-аутентификации. По умолчанию при межсайтовых вызовах fetch() или XMLHttpRequest браузеры не отправляют учётные данные.
Чтобы запрос fetch() включал учётные данные, задайте для параметра credentials значение "include".
Чтобы запрос XMLHttpRequest включал учётные данные, задайте для свойства XMLHttpRequest.withCredentials значение true.
В этом примере содержимое, изначально загруженное с https://foo.example, выполняет GET-запрос к ресурсу на https://bar.other, который устанавливает файлы cookie. Содержимое на foo.example может включать такой код JavaScript:
const url = "https://bar.other/resources/credentialed-content/";
const request = new Request(url, { credentials: "include" });
const fetchPromise = fetch(request);
fetchPromise.then((response) => console.log(response));
Этот код создаёт объект Request, задавая параметру credentials значение "include" в конструкторе, а затем передаёт этот запрос в fetch(). Поскольку это простой запрос GET, предварительная проверка для него не выполняется, но браузер отклонит любой ответ, в котором заголовку Access-Control-Allow-Credentials не присвоено значение true, и не предоставит ответ вызвавшему его веб-контенту.
Пример обмена данными между клиентом и сервером:
GET /resources/credentialed-content/ HTTP/1.1 Host: bar.other User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:71.0) Gecko/20100101 Firefox/71.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: en-us,en;q=0.5 Accept-Encoding: gzip,deflate Connection: keep-alive Referer: https://foo.example/examples/credential.html Origin: https://foo.example Cookie: pageAccess=2 HTTP/1.1 200 OK Date: Mon, 01 Dec 2008 01:34:52 GMT Server: Apache/2 Access-Control-Allow-Origin: https://foo.example Access-Control-Allow-Credentials: true Cache-Control: no-cache Pragma: no-cache Set-Cookie: pageAccess=3; expires=Wed, 31-Dec-2008 01:34:53 GMT Vary: Accept-Encoding, Origin Content-Encoding: gzip Content-Length: 106 Keep-Alive: timeout=2, max=100 Connection: Keep-Alive Content-Type: text/plain [text/plain content]
Хотя заголовок запроса Cookie содержит файл cookie, предназначенный для содержимого на https://bar.other, если бы bar.other не вернул заголовок Access-Control-Allow-Credentials со значением true, как показано в этом примере, браузер проигнорировал бы ответ и не предоставил его веб-контенту.
Предварительные запросы и учётные данные
Предварительные запросы CORS никогда не должны содержать учётные данные. В ответе на предварительный запрос должно быть указано Access-Control-Allow-Credentials: true, чтобы подтвердить, что фактический запрос можно выполнить с учётными данными.
Примечание: Некоторые корпоративные службы аутентификации требуют отправлять клиентские сертификаты TLS в предварительных запросах, что противоречит спецификации Fetch.
В Firefox 87 такое несоответствующее спецификации поведение можно включить, задав параметру настройки network.cors_preflight.allow_client_cert значение true (ошибка Firefox 1511151). Браузеры на основе Chromium в настоящее время всегда отправляют клиентские сертификаты TLS в предварительных запросах CORS (ошибка Chrome 775438).
Запросы с учётными данными и подстановочные символы
При ответе на запрос с учётными данными:
- Сервер не должен использовать подстановочный символ
*в значении заголовка ответаAccess-Control-Allow-Origin, а должен указать конкретный источник; например:Access-Control-Allow-Origin: https://example.com - Сервер не должен использовать подстановочный символ
*в значении заголовка ответаAccess-Control-Allow-Headers, а должен указать явный список имён заголовков; например,Access-Control-Allow-Headers: X-PINGOTHER, Content-Type - Сервер не должен использовать подстановочный символ
*в значении заголовка ответаAccess-Control-Allow-Methods, а должен указать явный список имён методов; например,Access-Control-Allow-Methods: POST, GET - Сервер не должен использовать подстановочный символ
*в значении заголовка ответаAccess-Control-Expose-Headers, а должен указать явный список имён заголовков; например,Access-Control-Expose-Headers: Content-Encoding, Kuma-Revision
Если запрос содержит учётные данные (чаще всего заголовок Cookie), а ответ включает заголовок Access-Control-Allow-Origin: * (то есть подстановочный символ), браузер заблокирует доступ к ответу и выведет ошибку CORS в консоли инструментов разработчика.
Но если запрос действительно содержит учётные данные (например, заголовок Cookie), а ответ содержит конкретный источник, а не подстановочный символ (например, Access-Control-Allow-Origin: https://example.com), браузер разрешит доступ к ответу для указанного источника.
Также обратите внимание: заголовок ответа Set-Cookie не установит файл cookie, если значение Access-Control-Allow-Origin в этом ответе — подстановочный символ *, а не конкретный источник.
Сторонние файлы cookie
Обратите внимание, что файлы cookie, устанавливаемые в ответах CORS, подчиняются обычным правилам использования сторонних файлов cookie. В приведённом выше примере страница загружается с foo.example, но заголовок Set-Cookie в ответе отправляется с bar.other, поэтому файл cookie не будет сохранён, если браузер пользователя настроен на отклонение всех сторонних файлов cookie.
Файлы cookie, устанавливаемые в запросах и ответах CORS, подчиняются обычным правилам использования сторонних файлов cookie.
Правила использования сторонних файлов cookie могут запрещать отправку таких файлов cookie в запросах, фактически не позволяя сайту отправлять запросы с учётными данными, даже если сторонний сервер разрешает это (с помощью Access-Control-Allow-Credentials). Правила по умолчанию различаются в разных браузерах, но могут задаваться с помощью атрибута SameSite.
Даже если запросы с учётными данными разрешены, браузер может быть настроен на отклонение всех сторонних файлов cookie в ответах.
Заголовки HTTP-ответа
В этом разделе перечислены заголовки HTTP-ответа, которые серверы возвращают для запросов управления доступом согласно спецификации межсайтового обмена ресурсами. В предыдущем разделе описано, как они используются.
Access-Control-Allow-Origin
Возвращаемый ресурс может содержать один заголовок Access-Control-Allow-Origin со следующим синтаксисом:
Access-Control-Allow-Origin: <origin> | *
Access-Control-Allow-Origin указывает либо один источник, разрешая браузерам предоставлять этому источнику доступ к ресурсу, либо — для запросов без учётных данных — подстановочный символ *, разрешая браузерам предоставлять доступ к ресурсу из любого источника.
Например, чтобы разрешить коду из источника https://mozilla.org доступ к ресурсу, можно указать:
Access-Control-Allow-Origin: https://mozilla.org Vary: Origin
Если сервер указывает один источник (который может динамически меняться в зависимости от источника запроса согласно списку разрешённых источников), а не подстановочный символ *, серверу также следует включить Origin в заголовок ответа Vary, чтобы сообщить клиентам, что ответы сервера будут различаться в зависимости от значения заголовка запроса Origin.
Access-Control-Expose-Headers
Заголовок Access-Control-Expose-Headers добавляет указанные заголовки в список разрешённых заголовков, к которым JavaScript (например, Response.headers) в браузерах может получать доступ.
Access-Control-Expose-Headers: <header-name>[, <header-name>]*
Например, следующий код разрешит браузеру получать доступ к заголовкам X-My-Custom-Header и X-Another-Custom-Header:
Access-Control-Expose-Headers: X-My-Custom-Header, X-Another-Custom-Header
Access-Control-Max-Age
Заголовок Access-Control-Max-Age указывает, как долго можно кэшировать результаты предварительного запроса. Примеры предварительных запросов приведены выше.
Access-Control-Max-Age: <delta-seconds>
Параметр delta-seconds указывает, сколько секунд можно кэшировать результаты.
Access-Control-Allow-Credentials
Заголовок Access-Control-Allow-Credentials указывает, можно ли предоставить доступ к ответу на запрос, если флаг credentials имеет значение true. Если он используется в ответе на предварительный запрос, то указывает, можно ли выполнить фактический запрос с учётными данными. Обратите внимание, что простые запросы GET не проходят предварительную проверку. Поэтому, если запрос к ресурсу отправляется с учётными данными, но в ответе отсутствует этот заголовок, браузер проигнорирует ответ и не предоставит его веб-контенту.
Access-Control-Allow-Credentials: true
Запросы с учётными данными описаны выше.
Access-Control-Allow-Methods
Заголовок Access-Control-Allow-Methods указывает метод или методы, разрешённые при доступе к ресурсу. Он используется в ответе на предварительный запрос. Условия, при которых запрос выполняется как предварительный, рассмотрены выше.
Access-Control-Allow-Methods: <method>[, <method>]*
Выше приведён пример предварительного запроса, в том числе пример отправки этого заголовка браузеру.
Access-Control-Allow-Headers
Заголовок Access-Control-Allow-Headers используется в ответе на предварительный запрос, чтобы указать, какие заголовки HTTP можно использовать при выполнении фактического запроса. Этот заголовок представляет собой ответ сервера на заголовок браузера Access-Control-Request-Headers.
Access-Control-Allow-Headers: <header-name>[, <header-name>]*
Заголовки HTTP-запроса
В этом разделе перечислены заголовки, которые клиенты могут использовать при отправке HTTP-запросов для работы с функцией совместного использования ресурсов между источниками. Обратите внимание: при отправке запросов серверам эти заголовки устанавливаются автоматически. Разработчикам, отправляющим запросы между источниками, не нужно программно задавать какие-либо заголовки запросов для совместного использования ресурсов между источниками.
Origin
Заголовок Origin указывает источник запроса на доступ между источниками или предварительного запроса.
Origin: <origin>
Источник — это URL-адрес, указывающий сервер, с которого отправляется запрос. Он не содержит сведений о пути — только имя сервера.
Примечание: Значение origin может быть null.
Обратите внимание: в любом запросе на управление доступом заголовок Origin отправляется всегда.
Access-Control-Request-Method
Заголовок Access-Control-Request-Method используется при отправке предварительного запроса, чтобы сообщить серверу, какой метод HTTP будет применён при выполнении фактического запроса.
Access-Control-Request-Method: <method>
Примеры такого использования приведены выше.
Access-Control-Request-Headers
Заголовок Access-Control-Request-Headers используется при отправке предварительного запроса, чтобы сообщить серверу, какие заголовки HTTP будут использоваться при выполнении фактического запроса (например, передавая их в параметре headers). На этот заголовок со стороны браузера отвечает соответствующий заголовок сервера Access-Control-Allow-Headers.
Access-Control-Request-Headers: <field-name>[,<field-name>]*
Примеры такого использования приведены выше.
Спецификации
| Спецификация |
|---|
| Fetch> # http-access-control-allow-origin> |
Совместимость с браузерами
| Компьютеры | Мобильные устройства | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox для Android | Opera Android | Safari на iOS | Samsung Internet | WebView Android | WebView на iOS | |
CORS |
4 | 12 | 3.5 | 12 | 4 | 18 | 4 | 12 | 3.2 | 1.0 | 2 | 3.2 |
См. также
- Ошибки CORS
- Включение CORS: как добавить поддержку CORS на сервере
- Fetch API
XMLHttpRequest- Сработает ли CORS? — интерактивное объяснение и генератор CORS
- Как запустить браузер Chrome без CORS
- Использование CORS во всех современных браузерах
-
Ответ на Stack Overflow с инструкциями по решению распространённых проблем:
- Как избежать предварительного запроса CORS
- Как использовать прокси-сервер CORS, чтобы обойти ошибку «Отсутствует заголовок Access-Control-Allow-Origin»
- Как исправить ошибку «Заголовок Access-Control-Allow-Origin не должен содержать подстановочный знак»
© 2005–2025 MDN contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CORS