В этой статье в основном рассматриваются три междоменных метода: JSONP, CORS, postMessage.
Вопрос. Почему возникают междоменные проблемы?
О: Из-за ограничений политики браузера в отношении одного и того же источника браузер будет отклонять запросы из разных источников.
*Примечание. Строго говоря, браузер не отклоняет все междоменные запросы, но фактически отклоняет операции междоменного чтения. Политика ограничения одного и того же происхождения в браузере применяется следующим образом:
- Обычно браузеры разрешают записи из разных источников, такие как ссылки и перенаправления;
- Обычно браузеры разрешают встраивание разных источников, например теги img, script;
- Обычно браузеры не разрешают чтение из разных источников. *
В: Что считается междоменным?
О: Все запросы из разных доменов являются междоменными. Глоссарий:Тот же источник — две страницы принадлежат одному и тому же источнику, если они имеют один и тот же протокол, порт и хост.Вопрос. Почему существуют междоменные требования?
A: Сценарий - После того, как проект обслуживается, сервисы с разными обязанностями разбросаны по разным проектам.Часто доменные имена этих проектов разные, но одному требованию может потребоваться соответствие нескольким сервисам, и тогда интерфейсы разных сервисов должны быть называться. , поэтому возникает междоменный домен.
Как добиться междоменного
Как правило, чаще всего используются следующие междоменные методы: JSONP, CORS и postMessage.
JSONP
Трюк, созданный исключительно для реализации междоменных запросов.
【Принцип реализации】
Хотя из-за влияния политики одного и того же источника данные из разных доменов (перекрестное чтение) нельзя запрашивать через XMLHttpRequest. Тем не менее, на странице можно размещать файлы сценариев js в разных доменах (внедрение из разных источников). Таким образом, после загрузки js-файла срабатывает обратный вызов, и в качестве параметра можно передать необходимые данные.
[метод реализации (требуется сотрудничество между интерфейсом и сервером)]
<script type="text/javascript">
function dosomething(data){
//处理获得的数据
}
</script>
<script src="http://example.com/data.php?callback=dosomething"></script>
<?php
$callback = $_GET['callback'];//得到回调函数名
$data = array('a','b','c');//要返回的数据
echo $callback.'('.json_encode($data).')';//输出
?>
[Преимущества и недостатки JSONP]
Достоинства: хорошая совместимость (совместим с младшими версиями IE)
Недостатки: 1. JSONP поддерживает только запросы GET 2. XMLHttpRequest имеет лучший механизм обработки ошибок, чем JSONP
CORS
CORS — это новое официальное решение, рекомендованное W3C, которое позволяет серверам поддерживать междоменные запросы XMLHttpRequest. CORS очень удобен в реализации, нужно только добавить некоторые HTTP-заголовки, чтобы сервер мог объявить разрешенный источник доступа.
Стоит отметить, что при обычном использовании CORS асинхронные запросы делятся на простые запросы и непростые запросы, разница между непростыми запросами в том, что сначала отправляется предварительный запрос.
【Простой запрос】
Используйте один из следующих методов без ручной настройки полей заголовка, отличных от набора полей заголовка CORS-safe:
- GET
- HEAD
- POST
- 仅当POST方法的Content-Type值等于下列之一才算作简单请求 - text/plain - multipart/form-data - application/x-www-form-urlencoded
Сообщение запроса:
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
Строка 10 сообщения запроса: Происхождение:foo.exampleУказывает, что запрос исходит отfoo.пример.
Ответное сообщение:
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]
Строка 4 ответного сообщения: Access-Control-Allow-Origin: * указывает, что к ресурсу может получить доступ любой внешний домен.
【Непростой запрос】
- Был использован любой из следующих методов HTTP:
- PUT
- DELETE
- CONNECT
- OPTIONS
- TRACE
- PATCH
- Искусственно задайте другие поля заголовка, отличные от поля заголовка CORS-safe. Коллекция:
- Accept
- Accept-Language
- Content-Language
- Content-Type (but note the additional requirements below)
- DPR
- Downlink
- Save-Data
- Viewport-Width
- Width
- Значение Content-Type не является одним из следующих:
- application/x-www-form-urlencoded
- multipart/form-data
- text/plain
Перед отправкой реального запроса сначала будет отправлен предварительный запрос, как показано на рисунке:
1. Первый OPTIONS — это предварительный запрос, который содержит следующие два поля заголовка:
Access-Control-Request-Method: POST
Access-Control-Request-Headers: X-PINGOTHER
Метод Access-Control-Request-Method: POST в запросе предварительного запроса должен сообщить серверу, что фактический запрос после этого будет использовать метод POST.
Access-Control-Request-Headers сообщает серверу, что фактический запрос будет содержать два настраиваемых поля заголовка запроса: X-PINGOTHER и Content-Type. На основании этого сервер решает, разрешен ли фактический запрос или нет.
В ответе на предварительный запрос
Access-Control-Allow-Origin: foo.example// Определите приемлемые источники междоменных запросов;
Access-Control-Allow-Methods: POST, GET, OPTIONS //Определяет допустимые методы междоменных запросов, такие как GET, POST, OPTIONS;
Access-control-allow-headers: x-pingother, content-type // определяет допустимый пользовательский заголовок междоменного запроса;
Максимальный возраст контроля доступа: 86400. //Определяет действительное время (секунды) данного предзапроса, в течение которого нет необходимости отправлять предзапрос;
Запросы XMLHttpRequest могут отправлять запросы учетных данных (файлы cookie HTTP и данные аутентификации), обычноНе будетОтправка учетных данных между доменами, но в некоторых случаях необходимо открыть разные состояния входа, поэтому, если вы хотите отправить учетные данные, вам необходимо установить специальный флаг XMLHttpRequest. Например, в следующем коде можно задать для withCredentials XMLHttpRequest значение true, чтобы браузер мог отправлять учетные данные между доменами.
var xhr = new XMLHttpRequest();
xhr.withCredentials = true;
Когда поле Access-Control-Allow-Credentials в заголовке ответа, возвращаемом сервером, существует и имеет значение true, браузер передаст результат ответа клиентской программе. Кроме того, Access-Control-Allow-Origin должен указывать доменное имя источника запроса, иначе ответ не будет получен.
HTTP/1.1 200 OK
Access-Control-Allow-Origin: http://foo.com
Access-Control-Allow-Credentials: true
Set-Cookie: pageAccess=3; expires=Wed, 31-Dec-2008 01:34:53 GMT
Keep-Alive: timeout=2, max=100
Connection: Keep-Alive
Content-Type: text/plain
На следующем рисунке показана блок-схема запроса с учетными данными:
postMessage
Метод window.postMessage(message,targetOrigin) — это новая функция html5. Его можно использовать для отправки сообщений другим оконным объектам, независимо от того, относятся ли оконные объекты к одному или разным источникам. , Chrome, Opera и т. д. Все браузеры уже поддерживают метод window.postMessage.
otherWindow.postMessage(message, targetOrigin, [transfer]);