Кроссдоменный AJAX запрос

Автор: Eugeniy Marilev
Дата публикации: 2013-09-17 04:32:40
«Почему не получается сделать запрос AJAX на другой домен?». Данный вопрос задается довольно часто, причем не только начинающими специалистами. Ответ - это сделано в целях безопасности — для того, чтобы каким-либо образом попавшие на страницу сайта скрипты не могли отправить данные на удаленный сервер. Ведь запущенный клиентский скрипт может получить содержимое cookies, настройки пользователя, и т.п. клиентскую конфиденциальную информацию. Если честно, мне кажется это глупым решением, т.к. в любом случае в javascript остается возможность, работая с DOM деревом документа добавить в раздел <head> скрипт с произвольным адресом, что является заменой пользовательского AJAX запроса. Да, конечно, так нельзя будет переслать файл, т.к. при подключении скрипта посылается GET-запрос. GET ограничен по объему пересылаемых данных, но этого объема более чем достаточно, чтобы передать на сторонний сервер, например, идентификатор сессии пользователя. Существует два решения данной проблемы:
  1. Установка и настройка модуля веб-сервера, занимающегося перезаписью заголовков запросов.
  2. Вариант с подключением скриптов в блок <head> страницы. Лучше всего реализовать с помощью "jsonp" AJAX-запроса библиотеки jQuery.
Далее рассмотрим оба варианта подробнее.

Настройка веб-сервера для кроссдоменных AJAX запросов

Рассмотрим на примере сервера Apache2 для debian:
  1. Включить модуль headers:
    sudo a2enmod headers
  2. Настроить в виртуальном хосте возвращаемый заголовок:
    Header set Access-Control-Allow-Origin *
  3. Перегрузить конфигурацию сервера:
    sudo /etc/init.d/apache2 reload
Подробнее и для других веб-серверов можно посмотреть здесь. Преимущества:
  1. Максимальный эффект при минимальных временных затратах
  2. Гибкость настройки. Здесь можно разрешить обращения к только для определенных адресов.
Недостатки:
  1. Данный вариант все равно не решает проблему для браузеров семейства Internet Explorer.

JQuery AJAX с типом "jsonp"

По факту проблема возникает из-за того, что при посылке кроссдоменного запроса браузер не удерживает соединение и прерывает его не получая нужных заголовков. Мы же хотим выполнить определенный код после того, как сервер отдаст нас ответ. Обычно ответ представляется в формате json или же xml. Для обхода этого предлагается следующий вариант. При посылке запроса на сервер передается строковый параметр "callback". Например, http://mysite.com/ajax/data?callback=my_callback_function. Таким образом, мы даем указание веб-серверу, что результаты, которые будут возвращены нужно обработать функцией "my_callback_function". Получается, все что остается — в результирующем ответе веб-сервер должен данные обрамить в функцию-callback, примерно так:
my_callback_function(data), где data — возвращаемые данные, например, следующей структуры - {param1: value1, param2: value2}.
Подобная реализация клиентских запросов реализована уже в библиотеке jQuery. Для того, чтобы послать вышеописанного типа запрос на удаленный адрес нужно указать функции jQuery.ajax параметром тип получаемых с сервера данных - "jsonp". Выглядеть это должно так:
$.ajax({
    url: "http://mysite.com/ajax/data",
    data: {param1: value1, param2: value2},
    jsonpCallback: "my_callback_function",
    dataType: "jsonp"
});
Преимущества данного варианта:
  1. работает кроссбраузерно
  2. прост в реализации
  3. не требует дополнительных настроек сервера
Недостатки данного варианта:
  1. Так как мы может посылать только GET-запросы, то получаем ограничение на размер запроса
  2. Нужно по разному реализовывать логику запросов к текущему домену и сторонних доменов.
  3. Невозможно выполнить необходимый код, если сервер по каким-либо причинам возвращает код ошибки.
Комментарии к статье
Комментарии:
Нет результатов.
Только зарегистрированые пользователи могут оставлять комментарии