перекрестный домен

внешний интерфейс сервер JavaScript браузер

В этой статье в основном рассматриваются три междоменных метода: JSONP, CORS, postMessage.

Вопрос. Почему возникают междоменные проблемы?
О: Из-за ограничений политики браузера в отношении одного и того же источника браузер будет отклонять запросы из разных источников.
*Примечание. Строго говоря, браузер не отклоняет все междоменные запросы, но фактически отклоняет операции междоменного чтения. Политика ограничения одного и того же происхождения в браузере применяется следующим образом:

  • Обычно браузеры разрешают записи из разных источников, такие как ссылки и перенаправления;
  • Обычно браузеры разрешают встраивание разных источников, например теги img, script;
  • Обычно браузеры не разрешают чтение из разных источников. *

В: Что считается междоменным?
О: Все запросы из разных доменов являются междоменными. Глоссарий:Тот же источник — две страницы принадлежат одному и тому же источнику, если они имеют один и тот же протокол, порт и хост.

img01
img01

Вопрос. Почему существуют междоменные требования?
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: * указывает, что к ресурсу может получить доступ любой внешний домен.

【Непростой запрос】

  1. Был использован любой из следующих методов HTTP:
  • PUT
  • DELETE
  • CONNECT
  • OPTIONS
  • TRACE
  • PATCH
  1. Искусственно задайте другие поля заголовка, отличные от поля заголовка CORS-safe. Коллекция:
  • Accept
  • Accept-Language
  • Content-Language
  • Content-Type (but note the additional requirements below)
  • DPR
  • Downlink
  • Save-Data
  • Viewport-Width
  • Width
  1. Значение Content-Type не является одним из следующих:
  • application/x-www-form-urlencoded
  • multipart/form-data
  • text/plain

Перед отправкой реального запроса сначала будет отправлен предварительный запрос, как показано на рисунке:

img02
img02

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

На следующем рисунке показана блок-схема запроса с учетными данными:

img03
img03

postMessage

Метод window.postMessage(message,targetOrigin) — это новая функция html5. Его можно использовать для отправки сообщений другим оконным объектам, независимо от того, относятся ли оконные объекты к одному или разным источникам. , Chrome, Opera и т. д. Все браузеры уже поддерживают метод window.postMessage.

otherWindow.postMessage(message, targetOrigin, [transfer]);