Это позволяет браузеру выдавать запросы XMLHttpRequest на серверы кросс-инцигина, тем самым преодолевая ограничение, которое Ajax может использоваться только в том же происхождении.
Эта статья подробно представляет внутренний механизм CORS.
(Фотография Описание: Снято в Оазис -парке в Аль -Айн, ОАЭ)
1. Введение
CORS требует поддержки браузера и сервера. В настоящее время все браузеры поддерживают эту функцию, а браузер IE не может быть ниже, чем IE10.
Весь процесс связи CORS автоматически завершается браузером и не требует участия пользователей. Для разработчиков CORS Communication ничем не отличается от одной и той же связи Ajax, и код точно такой же. Как только браузер обнаружит, что AJAX запрашивает кросс-аоригин, он автоматически добавит некоторую дополнительную информацию заголовка, а иногда будет дополнительный запрос, но пользователь не будет ее чувствовать.
Следовательно, ключом к реализации связи CORS является сервер. Пока сервер реализует интерфейс CORS, может быть выполнена перекрестная связь.
Два запроса
Браузер разделяет запросы CORS на две категории: простой запрос и не такой такой же такой запрос.
Пока следующие два основных условия выполняются одновременно, это простой запрос.
(1) Метод запроса является одним из следующих трех методов:
HeadgetPost
(2) Информация о заголовке HTTP не превышает следующие поля:
AcceptAccept-LanguageNtent-LanguageLast-event-IdContent-Type: только ограничено тремя значениями application/x-www-form-urlencoded , multipart/form-data , text/plain
Любой, кто не соответствует двум вышеупомянутым условиям одновременно,-это не простой просьба.
Обработка браузера с этими двумя запросами отличается.
3. Простой запрос 3.1 Базовый процесс
Для простых запросов браузер напрямую выпускает запрос CORS. В частности, добавьте поле Origin в информацию о заголовке.
Ниже приведен пример. Браузер обнаружил, что этот запрос Ajax поперечного происхождения был простым запросом, и он автоматически добавил поле Origin в информацию о заголовке.
GET /cors HTTP/1.1Origin: http://api.bob.comHost: api.alice.comAccept-Language: en-USConnection: keep-aliveUser-Agent: Mozilla/5.0...
В приведенной выше информации заголовок поле Origin используется для указания того, какой источник (Protocol + Domain Name + Port) запрос исходит. Основываясь на этом значении, сервер решает, соглашаться ли запрос.
Если источник, указанный по Origin , не находится в рамках разрешения, сервер вернет обычный HTTP -ответ. Браузер обнаружил, что информация о заголовке этого ответа не содержит поля Access-Control-Allow-Origin (для получения подробной информации см. Ниже), поэтому было известно, что произошла ошибка, и, таким образом, была выбрана ошибка, которая была захвачена функцией обратного вызова onerror XMLHttpRequest . Обратите внимание, что эта ошибка не может быть идентифицирована кодом состояния, поскольку код состояния ответа HTTP может быть 200.
Если доменное имя, указанное по Origin находится в рамках разрешения, ответ, возвращаемый сервером, будет иметь несколько дополнительных полей заголовка.
Access-Control-Allow-Origin: http://api.bob.comAccess-Control-Allow-Credentials: trueAccess-Control-Expose-Headers: FooBarContent-Type: text/html; charset=utf-8
Среди приведенной выше информации заголовка есть три поля, связанные с запросами CORS, все начинаются с Access-Control- .
(1) Контроль-контроль-авооригин
Это поле обязательно к заполнению. Его значение является либо значением поля Origin во время запроса, либо * , что указывает на то, что запрос на любое доменное имя принят.
(2) Контроль доступа
Это поле необязательно. Его значение - это логическое значение, указывающее, разрешать ли отправлять файлы cookie. По умолчанию файлы cookie не включены в запросы CORS. Установите на true , что означает, что сервер явно допускает это. Файлы cookie могут быть включены в запрос и отправлены на сервер вместе. Это значение может быть установлено только на true . Если сервер не отправляет файлы cookie в браузере, удалите поле.
(3) Управляющие доступа
Это поле необязательно. Когда CORS запрашивает, метод getResponseHeader() объекта XMLHttpRequest может получить только 6 базовых полей: Cache-Control , Content-Language , Content-Type , Expires , Last-Modified , Pragma . Если вы хотите получить другие поля, вы должны указать их в Access-Control-Expose-Headers . Приведенный выше пример указывает, что getResponseHeader('FooBar') может вернуть значение поля FooBar .
3.2 Атрибут с Credentials
Как упомянуто выше, запросы CORS не отправляют файлы cookie и информацию о аутентификации HTTP по умолчанию. Если вы хотите отправить файлы cookie на сервер, с одной стороны, вам нужно, чтобы сервер согласился и указал поле Access-Control-Allow-Credentials .
Access-Control-Allow-Credentials: true С другой стороны, разработчик должен открыть свойство withCredentials в запросе Ajax.
var xhr = new XMLHttpRequest();xhr.withCredentials = true;В противном случае браузер не отправит, даже если сервер согласится отправлять файлы cookie. В качестве альтернативы, сервер требует установки файлов cookie, и браузер не будет справляться с ним.
Тем не менее, если настройка withCredentials опущена, некоторые браузеры все равно будут отправлять файлы cookie вместе. В настоящее время вы можете явно близко withCredentials .
xhr.withCredentials = false; Следует отметить, что если вы хотите отправить файлы cookie, Access-Control-Allow-Origin не может быть установлен в качестве звездочки, и вы должны указать явное доменное имя, которое согласуется с запрошенной веб-страницей. В то же время, файлы cookie по-прежнему следуют той же политике. Будут загружены только файлы cookie с именами доменных доменов. Файлы cookie из других доменных имен не будут загружены, и document.cookie в исходном коде веб-страницы (межоригинальный) не может считывать файлы cookie под именем домена сервера.
4. Несомазый запрос 4.1 Запрос перед полетом
Несоточный запрос-это запрос, который имеет особые требования для сервера, например, метод запроса PUT или DELETE , или тип поля Content-Type - application/json .
Запрос CORS, который не является простым запросом, добавит запрос на запрос HTTP перед официальным сообщением, которое называется запросом «предварительно полезной».
Сначала браузер спрашивает сервер, находится ли доменное имя, на котором находится текущая веб -страница, в списке лицензий сервера, и какие глаголы HTTP могут использоваться. Только когда будет получен положительный ответ, браузер выпустит формальный запрос XMLHttpRequest , в противном случае сообщается об ошибке.
Ниже приведен сценарий браузера JavaScript.
var url = 'http://api.alice.com/cors';var xhr = new XMLHttpRequest();xhr.open('PUT', url, true);xhr.setRequestHeader('X-Custom-Header', 'value');xhr.send();
В приведенном выше коде метод HTTP-запроса PUT и отправляет пользовательскую информацию о X-Custom-Header .
Браузер обнаружил, что это был непреодолимый запрос, поэтому он автоматически выпустил запрос «перед полетом», требующий от сервера подтвердить, что это может быть запрошено. Ниже приведена информация о заголовке HTTP для этого запроса «предварительная полета».
OPTIONS /cors HTTP/1.1Origin: http://api.bob.comAccess-Control-Request-Method: PUTAccess-Control-Request-Headers: X-Custom-HeaderHost: api.alice.comAccept-Language: en-USConnection: keep-aliveUser-Agent: Mozilla/5.0... Метод запроса, используемый в запросе «Предульзя», является OPTIONS , указывающий, что этот запрос используется для запроса. В информации заголовка полевым полем является Origin , указывающее, из какого источника поступает запрос.
В дополнение к полю Origin , информация о заголовке запроса «Предульья» включает в себя два специальных поля.
(1) Контроль доступа-метеод
Это поле необходимо для перечисления, какие методы HTTP будут использоваться для запроса CORS браузера. Приведенный выше пример PUT .
(2) Управление доступа
Это поле представляет собой разделенную запятую строку, которая определяет дополнительное поле информации о заголовке, которое отправит запрос Browser CORS. Приведенный выше пример- X-Custom-Header .
4.2 Ответ на запросы перед полетом
После того, как сервер получает запрос «Предульзя», после проверки Origin , Access-Control-Request-Method Access-Control-Request-Headers , подтвердите, что запросы перекрестного происхождения разрешены, и вы можете ответить.
HTTP/1.1 200 OKDate: Mon, 01 Dec 2008 01:15:39 GMTServer: Apache/2.0.61 (Unix)Access-Control-Allow-Origin: http://api.bob.comAccess-Control-Allow-Methods: GET, POST, PUTAccess-Control-Allow-Headers: X-Custom-HeaderContent-Type: text/html; charset=utf-8Content-Encoding: gzipContent-Length: 0Keep-Alive: timeout=2, max=100Connection: Keep-AliveContent-Type: text/plain
В приведенном выше ответе HTTP ключом является поле Access-Control-Allow-Origin , что означает, что http://api.bob.com может запросить данные. Это поле также может быть установлено на звездочку, чтобы согласиться с любым перекрестным запросом.
Access-Control-Allow-Origin: *
Если браузер отрицает запрос «Предульти», будет возвращен нормальный HTTP-ответ, но нет никаких полей заголовка, связанных с CORS. В настоящее время браузер определит, что сервер не согласен с запросом на предварительную работу, поэтому ошибка запускается и захватывается функцией обратного вызова onerror в объекте XMLHttpRequest . Консоль распечатает следующее сообщение об ошибке.
XMLHttpRequest cannot load http://api.alice.com.Origin http://api.bob.com is not allowed by Access-Control-Allow-Origin.
Другие поля, связанные с CORS, на которые реагирует сервер, являются следующими.
Access-Control-Allow-Methods: GET, POST, PUTAccess-Control-Allow-Headers: X-Custom-HeaderAccess-Control-Allow-Credentials: trueAccess-Control-Max-Age: 1728000(1) Методы управления доступа
Это поле требуется, и его значение представляет собой разделенную запятую строку, указывающую все методы перекрестного запроса, поддерживаемые сервером. Обратите внимание, что все поддерживаемые методы возвращаются, а не только тот, который запросил браузер. Это значит избежать нескольких запросов «предварительного полета».
(2) Управление доступа
Если запрос браузера включает в себя поле Access-Control-Request-Headers , требуется поле Access-Control-Allow-Headers . Это также разделенная запятая строка, указывающая, что все поля заголовка, поддерживаемые сервером, не ограничиваются полями, запрашиваемыми браузером в «Предварительной полете».
(3) Контроль Access-Credentials
Это поле имеет то же значение, что и когда его запросили простым способом.
(4) Access-Control-Max-Age
Это поле не является обязательным и используется для указания периода достоверности этого запроса на предварительную работу, в считанные секунды. В приведенных выше результатах период достоверности составляет 20 дней (1728 000 секунд), что означает, что ответ кэшируется в течение 1728 000 секунд (то есть 20 дней). В течение этого периода не требуется другой запрос на предварительный полевой полет.
4.3 Нормальные запросы и ответы из браузера
После того, как сервер передает запрос «Предульзя», каждый раз, когда обычный запрос браузера CORS будет таким же, как и простой запрос, появится поле информации о заголовке Origin . Ответ сервера также будет иметь поле заголовка Access-Control-Allow-Origin .
Ниже приведен обычный запрос CORS браузера после запроса «Предульти».
PUT /cors HTTP/1.1Origin: http://api.bob.comHost: api.alice.comX-Custom-Header: valueAccept-Language: en-USConnection: keep-aliveUser-Agent: Mozilla/5.0...
Поле Origin приведенной выше информации заголовка автоматически добавляется браузером.
Ниже приведен нормальный ответ с сервера.
Access-Control-Allow-Origin: http://api.bob.comContent-Type: text/html; charset=utf-8
В приведенной выше информации заголовок поле-поля Access-Control-Allow-Origin должно быть включено в каждый ответ.
5. Сравнение с JSONP
CORS используется в той же цели, что и JSONP, но он более мощный, чем JSONP.
JSONP только поддерживает запросы GET , CORS поддерживает все типы HTTP -запросов. Преимущество JSONP заключается в том, что он поддерживает старомодные браузеры и может запросить данные на веб-сайтах, которые не поддерживают CORS.
(над)