Cross-Origin Resource Sharing (CORS) — механизм, использующий дополнительные HTTP-заголовки, чтобы дать возможность агенту пользователя получать разрешения на доступ к выбранным ресурсам с сервера на источнике (домене), отличном от того, что сайт использует в данный момент. Говорят, что агент пользователя делает запрос с другого источника (cross-origin HTTP request), если источник текущего документа отличается от запрашиваемого ресурса доменом, протоколом или портом.
Пример cross-origin запроса: HTML страница, обслуживаемая сервером с http://domain-a.com
, запрашивает <img> src
по адресу http://domain-b.com/image.jpg
. Сегодня многие страницы загружают ресурсы вроде CSS-стилей, изображений и скриптов с разных доменов, соответствующих разным сетям доставки контента (Content delivery networks, CDNs).
В целях безопасности браузеры ограничивают cross-origin запросы, инициируемые скриптами. Например, XMLHttpRequest
и Fetch API следуют политике одного источника (same-origin policy). Это значит, что web-приложения, использующие такие API, могут запрашивать HTTP-ресурсы только с того домена, с которого были загружены, пока не будут использованы CORS-заголовки.
Механизм CORS поддерживает кросс-доменные запросы и передачу данных между браузером и web-серверами по защищенному соединению. Современные браузеры используют CORS в API-контейнерах, таких как XMLHttpRequest
или Fetch, чтобы снизить риски, присущие запросам с других источников.
Кто должен читать данную статью?
На самом деле, все.
Конкретнее, эта статья для web-администраторов, разработчиков серверной стороны и front-end разработчиков. Современные браузеры поддерживают клиентские компоненты cross-origin обмена, включая заголовки и соблюдение правил политики. Но этот новый стандарт означает, что сервера также должны поддерживать новые заголовки запросов и ответов. Другая статья для разработчиков серверной части, описывающая перспективы сross-origin обмена на стороне сервера (с примерами кода на PHP), к дополнительному прочтению.
Какие запросы используют CORS?
Этот cтандарт сross-origin обмена используется для разрешения кросс-сайтовых HTTP запросов для:
- Вызова
XMLHttpRequest
или Fetch APIs в кросс-сайт манере, как описано выше. - Web Fonts (для кросс-доменного использования шрифтов в
@font-face
в рамках CSS), чтобы серверы могли разворачивать TrueType шрифты, которые могут быть загружены только кросс-сайт и использованы web-сайтами, которым это разрешено. - WebGL текстуры.
- Фреймы с изображениями/видео, добавленными в канвас с помощью
drawImage
. - Стили (для CSSOM доступа).
- Скрипты (для отключенных исключений).
Эта статья описывает общие понятия Cross-Origin Resource Sharing и включает обсуждение необходимых HTTP заголовков.
Обзор функциональности
Стандарт Cross-Origin Resource Sharing работает с помощью добавления новых HTTP-заголовков, которые позволяют серверам описывать набор источников, которым разрешено читать информацию, запрашиваемую web-браузером. В частности, для методов HTTP-запросов, которые могут привести к побочным эффектам над данными сервера (в частности, для HTTP методов, отличных от GET
или для POST
запросов, использующих определнные MIME-типы), спецификация требует, чтобы браузеры "предпроверяли" запрос, запрашивая поддерживающие методы с сервера с помощью метода HTTP-запроса OPTIONS
и затем, поверх "подтверждения" с сервера, отсылали фактический запрос с фактическим методом HTTP-запроса. Сервера также могут оповещать клиентов должны ли "полномочия" (включая Cookies и HTTP Authentication данные) быть отправлены с запросом.
Следующая секция описывает сценарии, а также предоставляет анализ использования HTTP-заголовков.
Примеры сценариев управления доступом
Здесь мы рассмотрим три сценария, которые иллюстрируют как Cross-Origin Resource Sharing работает. Каждый сценарий использует объект XMLHttpRequest
, который может быть использован для межсайтового взаимодействия, в любом, поддерживающем данный объект, браузере.
Фрагменты JavaScript кода, включенные в эти секции (а также фрагменты кода, отвечающие за корректную обработку межсерверных запросов, которые запускаются на сервере) могут быть испытаны "в действии" на http://arunranga.com/examples/access-control/, и будут работать в браузерах, которые поддерживают XMLHttpRequest
.
Обсуждение Cross-Origin Resource Sharing с точки зрения сервера (включая фрагменты кода на PHP) может быть найдено в статье Server-Side Access Control (CORS).
Простые запросы
Некоторые запросы не заставляют срабатывать CORS preflight. Они называются “простыми запросами” в данной статье, хотя Fetch спецификация, определяющая CORS, не использует этот термин. Запрос, для которого не срабатывает CORS preflight— так называемый “простой запросы”—это запрос, удовлетворяющий следующим условиям:
- Допустимые методы для запроса:
- Кроме заголовков, которые автоматические проставляются user-agent'ом (например,
Connection
,User-Agent
, или любой другой заголовок с именем, определенным в спецификации метода Fetch в секции “Запрещенные имена заголовков (которые нельзя изменить программно)”), допустимыми заголовками, которые могут быть проставлены вручную, являются те заголовки, которые определены спецификацией метода Fetch как “CORS-безопасные заголовки запроса”, такие как:Accept
Accept-Language
Content-Language
Content-Type
(но учитывайте примечание ниже)Last-Event-ID
DPR
Save-Data
Viewport-Width
Width
- Допустимыми значениями заголовка
Content-Type
являются:application/x-www-form-urlencoded
multipart/form-data
text/plain
- Не должны быть зарегистрированы обработчики событий на любой объект
XMLHttpRequestUpload
используемый в запросе; это достигается использованием свойстваXMLHttpRequest.upload
. - В запросе не должен использоваться объект типа
ReadableStream
.
Accept
, Accept-Language
, и Content-Language
. Если любой из этих заголовков имеет "нестандартное" значение, WebKit/Safari используют предварительный запрос. Значения, которые WebKit/Safari считают "нестандартными" для этих заголовков, перечислены только в следующих проблемах WebKit: Require preflight for non-standard CORS-safelisted request headers Accept, Accept-Language, and Content-Language, Allow commas in Accept, Accept-Language, and Content-Language request headers for simple CORS, и Switch to a blacklist model for restricted Accept headers in simple CORS requests. Во всех других браузерах подобных дополнительных ограничений нет, потому что они не являются частью спецификации.Например, представьте, что содержимое домена http://foo.example
хочет обратиться к содержимому http://bar.other
. На домене foo.example может использоваться следующий Javascript код:
var invocation = new XMLHttpRequest();
var url = 'http://bar.other/resources/public-data/';
function callOtherDomain() {
if(invocation) {
invocation.open('GET', url, true);
invocation.onreadystatechange = handler;
invocation.send();
}
}
Это приведет к простому обмену запросами между клиентом и сервером, используя CORS заголовки для обработки привилегий:
Посмотрим, что браузер отправит в таком случае на сервер, а также проверим ответ сервера:
GET /resources/public-data/ HTTP/1.1
Host: bar.other
User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1b3pre) Gecko/20081130 Minefield/3.1b3pre
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
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Connection: keep-alive
Referer: http://foo.example/examples/access-control/simpleXSInvocation.html
Origin: http://foo.example
HTTP/1.1 200 OK
Date: Mon, 01 Dec 2008 00:23:53 GMT
Server: Apache/2.0.61
Access-Control-Allow-Origin: *
Keep-Alive: timeout=2, max=100
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: application/xml
[XML Data]
Строчки 1 - 10 это заголовки отправленного запроса. Самим интересующим здесь для нас заголовком является Origin
, указанный на 10 строке. Данный заголовок указывает, что запрос пришел из содержимого домена http://foo.example
.
Строчки 13 - 22 показывают HTTP-ответ от сервера на домен http://bar.other
. В ответ сервер возвращает Access-Control-Allow-Origin
заголовок, указанный на 16 строке. Использование заголовков Origin
header и Access-Control-Allow-Origin
показывает протокол контроля доступа в простейшем виде. В этом случае, сервер отвечает с Access-Control-Allow-Origin: *
что означает, что к ресурсу может получить доступ с любого домена кросс-сайтовым способом. Если владелец ресурса http://bar.other
пожелал ограничить доступ к ресурсу для запросов только с http://foo.example
, они отправят обратно:
Access-Control-Allow-Origin: http://foo.example
Отметьте, никакой домен, кроме http://foo.example
(определен ORIGIN: заголовок в запросе, как в 10 строке выше), не может получить доступ к ресурсу кросс-сайтовым способом. Заголовок Access-Control-Allow-Origin
должен содержать значение, которое было отправлено в заголовке Origin
запроса.
Предварительные запросы
В отличии от “простых запросов” (обсуждено выше), "предварительные" запросы сначала отправляют HTTP-запрос методом OPTIONS
к ресурсу на другом домене, чтобы определить, является ли фактический запрос безопасным для отправки. Кросс-сайтовые запросы предварительно просматриваются таким образом, так как они могут быть причастны к пользовательским данным.
В частности, запрос предварительно просматривается, если выполняется любое из следующих условий:
- Если в запросе используется любой из следующих методов:
- Или если, кроме заголовков, автоматически устанавливаемых пользовательским агентом (например,
Connection
,User-Agent
, или любым другим заголовком с именем, определенным в спецификации Fetch как "имя запрещенного заголовка"), запрос включает любые заголовки, отличные от тех, которые спецификация Fetch определяет как "заголовок запроса CORS-безопасный заголовок запроса", а именно:Accept
Accept-Language
Content-Language
Content-Type
(но учтите дополнительные требования ниже)Last-Event-ID
DPR
Save-Data
Viewport-Width
Width
- Или если заголовок
Content-Type
содержит значение, отличное от следующих:application/x-www-form-urlencoded
multipart/form-data
text/plain
- Или если один или больше слушателей событий зарегистрированы на объекте
XMLHttpRequestUpload
, который используется в запросе. - Или если объект
ReadableStream
используется в запросе.
Ниже приведен пример запроса, который будет предварительно просмотрен.
var invocation = new XMLHttpRequest();
var url = 'http://bar.other/resources/post-here/';
var body = '<?xml version="1.0"?><person><name>Arun</name></person>';
function callOtherDomain(){
if(invocation)
{
invocation.open('POST', url, true);
invocation.setRequestHeader('X-PINGOTHER', 'pingpong');
invocation.setRequestHeader('Content-Type', 'application/xml');
invocation.onreadystatechange = handler;
invocation.send(body);
}
}
......
В примере выше, 3 строка создает XML тело, чтобы отправить POST
запросом на строке 8. Также, на строке 9, "кастомизированный" (не стандартный) заголовок HTTP запроса установлен (X-PINGOTHER: pingpong
). Такие заголовки не являются частью протокола HTTP/1.1, но, как правило, полезны для веб-приложений. Так как запрос использует Content-Type application/xml
, и так как установлен кастомизированный заголовок, этот запрос просматривается.
Замечнаие: как описано ниже, фактический POST
запрос не включает Access-Control-Request-*
заголовки; они нужны только для OPTIONS
запроса.
Давайте посмотрим на полный обмен между клиентом и сервером. Первый обмен - это предварительный запрос/ответ:
OPTIONS /resources/post-here/ HTTP/1.1 Host: bar.other User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1b3pre) Gecko/20081130 Minefield/3.1b3pre 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 Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7 Connection: keep-alive Origin: http://foo.example Access-Control-Request-Method: POST Access-Control-Request-Headers: X-PINGOTHER, Content-Type HTTP/1.1 200 OK Date: Mon, 01 Dec 2008 01:15:39 GMT Server: Apache/2.0.61 (Unix) Access-Control-Allow-Origin: http://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 Content-Encoding: gzip Content-Length: 0 Keep-Alive: timeout=2, max=100 Connection: Keep-Alive Content-Type: text/plain
Как только предварительный запрос завершен, отправляется настоящий запрос:
POST /resources/post-here/ HTTP/1.1 Host: bar.other User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1b3pre) Gecko/20081130 Minefield/3.1b3pre 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 Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7 Connection: keep-alive X-PINGOTHER: pingpong Content-Type: text/xml; charset=UTF-8 Referer: http://foo.example/examples/preflightInvocation.html Content-Length: 55 Origin: http://foo.example Pragma: no-cache Cache-Control: no-cache <?xml version="1.0"?><person><name>Arun</name></person> HTTP/1.1 200 OK Date: Mon, 01 Dec 2008 01:15:40 GMT Server: Apache/2.0.61 (Unix) Access-Control-Allow-Origin: http://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 GZIP'd payload]
Строки 1 - 12 выше представляют предварительный запрос с OPTIONS
методом. Браузер определяет, что ему нужно отправить это, основываясь на параметрах запроса, которые использовались во фрагменте кода JavaScript выше, чтобы сервер мог ответить, допустимо ли отправить запрос с фактическими параметрами запроса. OPTIONS - это метод HTTP/1.1, который используется для определения дополнительной информации от серверов, и является safe методом, что означает, что его нельзя использовать для изменения ресурса. Обратите внимание, что вместе с запросом OPTIONS отправляются два других заголовка запроса (строки 10 и 11 соответственно):
Access-Control-Request-Method: POST Access-Control-Request-Headers: X-PINGOTHER, Content-Type
Заголовок Access-Control-Request-Method
уведомляет сервер как часть предварительного запроса о том, что при отправке фактического запроса он будет отправлен методом запроса POST
. Заголовок Access-Control-Request-Headers
уведомляет сервер о том, что при отправке фактического запроса он будет отправлен с пользовательскими заголовками X-PINGOTHER
и Content-Type. Теперь у сервера есть возможность определить, хочет ли он принять запрос в этих обстоятельствах.
Строки 14 - 26 выше - это ответ, который сервер отправляет обратно, указывая, что метод запроса (POST
) и заголовки запроса (X-PINGOTHER
) являются приемлемыми. В частности, давайте посмотрим на строки 17-20:
Access-Control-Allow-Origin: http://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-Methods
и сообщает, что POST
, GET
, и OPTIONS
являются жизнеспособными методами для запроса соответствующего ресурса. Обратите внимание, что этот заголовок похож на заголовок ответа Allow
, но используется строго в контексте контроля доступа.
Сервер также отправляет Access-Control-Allow-Headers
со значением "X-PINGOTHER, Content-Type
", подтверждая, что это разрешенные заголовки, которые будут использоваться с фактическим запросом. Как и Access-Control-Allow-Methods
, Access-Control-Allow-Headers
представляет собой список допустимых заголовков через запятую.
Наконец, Access-Control-Max-Age
дает значение в секундах, в течение которого можно кэшировать ответ на предварительный запрос без отправки другого предварительного запроса. В этом случае, 86400 секунды - это 24 часа. Обратите внимание, что каждый браузер имеет максимальное внутреннее значение, которое имеет приоритет, когда Access-Control-Max-Age
больше.
Предварительные запросы и переадресации
Большинство браузеров в настоящее время не поддерживают следующие переадресации для предварительных запросов. Если переадресация происходит для предварительного запроса, большинство современных браузеров сообщат об ошибке, такой как следующее.
Запрос был перенаправлен на 'https://example.com/foo', который запрещен для запросов из разных источников, требующих предварительной проверки
Запрос требует предварительной проверки, которая запрещена для перенаправления между источниками
Протокол CORS изначально требовал такого поведения, но впоследствии был изменен, чтобы больше не требовать его. Однако большинство браузеров еще не реализовали это изменение и все еще демонстрируют поведение, которое требовалось изначально.
Поэтому, пока браузеры не догонят спецификацию, вы можете обойти это ограничение, выполнив одно или оба из следующих действий:
- изменить поведение на стороне сервера, чтобы избежать предварительной проверки и/или избежать переадресации — если у вас есть контроль над сервером, к которому делается запрос
- изменить запрос так, чтобы это был простой запрос, который не вызывает предварительную проверку
Но если невозможно внести эти изменения, то возможен другой способ:
- Сделайте простой запрос для определения (используя Response.url для Fetch API, или XHR.responseURL, чтобы определить, на каком URL завершится настоящий предварительный запрос).
- Сделайте другой запрос (“настоящий” запрос), используя URL адрес, полученный вами из Response.url или XMLHttpRequest.responseURL на первом этапе.
Однако, если запрос инициирует предварительную проверку из-за наличия в запросе заголовка `Authorization`, вы не сможете обойти ограничение, используя описанные выше шаги. И вы вообще не сможете обойти это, если у вас нет контроля над сервером, на который делается запрос.
Запросы с учетными данными
Наиболее интересная возможность, предоставляемая как XMLHttpRequest
, так и Fetch и CORS - это возможность делать "проверенные" запросы, которые осведомленны о файлах HTTP cookie и информации HTTP аутентификаци. По умолчанию, в кросс-сайтовых XMLHttpRequest
или Fetch вызовах, браузеры не отправляют учетные данные. Конкретный флаг должен быть установлен для объекта XMLHttpRequest
или конструктора Request
при его вызове.
В этом примере контент, изначально загруженный из http://foo.example,
выполняет простой GET запрос к ресурсу http://bar.other,
который устанавливает файлы сookie. Содержимое на foo.example может содержать такой JavaScript:
var invocation = new XMLHttpRequest();
var url = 'http://bar.other/resources/credentialed-content/';
function callOtherDomain(){
if(invocation) {
invocation.open('GET', url, true);
invocation.withCredentials = true;
invocation.onreadystatechange = handler;
invocation.send();
}
}
В строке 7 показан флаг XMLHttpRequest
, который должен быть установлен для выполнения вызова с помощью файлов cookie, а именно логическое значение withCredentials
. По умолчанию вызов выполняется без файлов cookie. Поскольку это простой запрос GET,
он не является предварительным, но браузер отклоняет любой ответ, который не имеет заголовка Access-Control-Allow-Credentials
: true
, и не создает ответ, доступный для вызова веб-контента.
Вот пример обмена между клентом и сервером:
GET /resources/access-control-with-credentials/ HTTP/1.1 Host: bar.other User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1b3pre) Gecko/20081130 Minefield/3.1b3pre 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 Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7 Connection: keep-alive Referer: http://foo.example/examples/credential.html Origin: http://foo.example Cookie: pageAccess=2 HTTP/1.1 200 OK Date: Mon, 01 Dec 2008 01:34:52 GMT Server: Apache/2.0.61 (Unix) PHP/4.4.7 mod_ssl/2.0.61 OpenSSL/0.9.7e mod_fastcgi/2.4.2 DAV/2 SVN/1.4.2 X-Powered-By: PHP/5.2.6 Access-Control-Allow-Origin: http://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 payload]
Также в строке 11 содержится Cookie, предназначенный для контента ресурса http://bar.other
. В случае если http://bar.other
не ответит полем Access-Control-Allow-Credentials
: true
(строка 19), то ответ от сервера будет проигнорирован и не станет доступным для веб-контента.
Запросы с учетными данными и wildcards
В процессе ответа на запрос с учетными данными сервер обязан указать точный источник в поле заголовка Access-Control-Allow-Origin
вместо спецсимвола "*
".
Из-за того что заголовки запроса в примере выше включают заголовок Cookie
, запрос провалился бы, если бы значение заголовка Control-Allow-Origin
было "*". Но он не провалился: потому что значение заголовка Access-Control-Allow-Origin
- "http://foo.example
" (действительный источник), а не спецсимвол "*
", контент, удостоверяющий полномочия, возвращается в вызывающий веб-контент.
Отметьте, что заголовок ответа Set-Cookie
в примере выше также устанавливает дополнительные куки. В случае неудачи, возникает исключение, в зависимости от используемого API.
Заголовки HTTP ответов
Эта секция содержит список заголовков HTTP ответов, которые сервер шлет в ответ на запрос доступа, как описано в спецификации совместного использования ресурсов между разными источниками. В предыдущей секции это описано в действии.
Access-Control-Allow-Origin
Возвращаемый ресурс может иметь один заголовок Access-Control-Allow-Origin
, синтаксис которого:
Access-Control-Allow-Origin: <origin> | *
Access-Control-Allow-Origin
определяет либо один источник, что указывает браузеру разрешить этому источнику доступ к ресурсу; либо — для запросов без учетных данных — значение "*
", которое говорит браузеру разрешить запросы из любых источников.
Например, чтобы разрешить http://mozilla.org доступ к ресурсу, можно указать:
Access-Control-Allow-Origin: http://mozilla.org
Если сервер возвращает название хоста, вместо "*", также может быть указан заголовок Vary со значением Origin, чтобы показать клиентам, что ответы с сервера будут отличаться в зависимости от значения заголовка запроса Origin.
Access-Control-Expose-Headers
The Access-Control-Expose-Headers
header lets a server whitelist headers that browsers are allowed to access. For example:
Access-Control-Expose-Headers: X-My-Custom-Header, X-Another-Custom-Header
This allows the X-My-Custom-Header
and X-Another-Custom-Header
headers to be exposed to the browser.
Access-Control-Max-Age
The Access-Control-Max-Age
header indicates how long the results of a preflight request can be cached. For an example of a preflight request, see the above examples.
Access-Control-Max-Age: <delta-seconds>
The delta-seconds
parameter indicates the number of seconds the results can be cached.
Access-Control-Allow-Credentials
The Access-Control-Allow-Credentials
header Indicates whether or not the response to the request can be exposed when the credentials
flag is true. When used as part of a response to a preflight request, this indicates whether or not the actual request can be made using credentials. Note that simple GET
requests are not preflighted, and so if a request is made for a resource with credentials, if this header is not returned with the resource, the response is ignored by the browser and not returned to web content.
Access-Control-Allow-Credentials: true
Credentialed requests are discussed above.
Access-Control-Allow-Methods
The Access-Control-Allow-Methods
header specifies the method or methods allowed when accessing the resource. This is used in response to a preflight request. The conditions under which a request is preflighted are discussed above.
Access-Control-Allow-Methods: <method>[, <method>]*
An example of a preflight request is given above, including an example which sends this header to the browser.
Access-Control-Allow-Headers
The Access-Control-Allow-Headers
header is used in response to a preflight request to indicate which HTTP headers can be used when making the actual request.
Access-Control-Allow-Headers: <field-name>[, <field-name>]*
The HTTP request headers
This section lists headers that clients may use when issuing HTTP requests in order to make use of the cross-origin sharing feature. Note that these headers are set for you when making invocations to servers. Developers using cross-site XMLHttpRequest
capability do not have to set any cross-origin sharing request headers programmatically.
Origin
The Origin
header indicates the origin of the cross-site access request or preflight request.
Origin: <origin>
The origin is a URI indicating the server from which the request initiated. It does not include any path information, but only the server name.
origin
can be the empty string; this is useful, for example, if the source is a data
URL.Note that in any access control request, the Origin
header is always sent.
Access-Control-Request-Method
The Access-Control-Request-Method
is used when issuing a preflight request to let the server know what HTTP method will be used when the actual request is made.
Access-Control-Request-Method: <method>
Examples of this usage can be found above.
Access-Control-Request-Headers
The Access-Control-Request-Headers
header is used when issuing a preflight request to let the server know what HTTP headers will be used when the actual request is made.
Access-Control-Request-Headers: <field-name>[, <field-name>]*
Examples of this usage can be found above.
Specifications
Specification | Status | Comment |
---|---|---|
Fetch Определение 'CORS' в этой спецификации. |
Живой стандарт | New definition; supplants W3C CORS specification. |
Browser compatibility
BCD tables only load in the browser
The compatibility table in this page is generated from structured data. If you'd like to contribute to the data, please check out https://github.com/mdn/browser-compat-data and send us a pull request.
Compatibility notes
- Internet Explorer 8 and 9 expose CORS via the
XDomainRequest
object, but have a full implementation in IE 10. - While Firefox 3.5 introduced support for cross-site XMLHttpRequests and Web Fonts, certain requests were limited until later versions. Specifically, Firefox 7 introduced the ability for cross-site HTTP requests for WebGL Textures, and Firefox 9 added support for Images drawn on a canvas using
drawImage
.
See also
- Code Samples Showing
XMLHttpRequest
and Cross-Origin Resource Sharing - Cross-Origin Resource Sharing From a Server-Side Perspective (PHP, etc.)
- Cross-Origin Resource Sharing specification
XMLHttpRequest
- Fetch API
- Using CORS with All (Modern) Browsers
- Using CORS - HTML5 Rocks
- Stack Overflow answer with “how to” info for dealing with common problems:
- How to avoid the CORS preflight
- How to use a CORS proxy to get around “No Access-Control-Allow-Origin header”
- How to fix “Access-Control-Allow-Origin header must not be the wildcard”