JQuery - Как удалить ограничение перекрестного домена

Я работаю над веб-приложением для мобильных устройств, а jsonp довольно круто для междоменного запроса, но API-сервер не поддерживает параметр обратного вызова. Поэтому я просто могу использовать json для извлечения данных с удаленного сервера.

Я попробовал json в jQuery, кажется, что он не поддерживает междоменный запрос. Я пробовал использовать функцию ajax-запроса на сафари, и он хорошо работает в междоменном пространстве, поэтому могу ли я удалить ограничение междоменной для json-запроса в jQuery? (не jsonp, только json), и как это сделать?

Или есть альтернативная простая ajax-библиотека (кросс-браузер) и может выполнять json по запросу междоменного доступа.

Ответ 1

Одинаковая политика происхождения

Вы пытаетесь обойти Одинаковая политика происхождения. Он встроен в каждый браузер и обычно не является чем-то, что вы можете или хотите отключить/обмениваться/etc. Это очень важный договор безопасности между вашим сайтом, пользователем и браузером пользователя.

CORS (возможно)

CORS позволяет веб-серверу указывать браузеры/клиенты, которым разрешен доступ к другому домену. Это делается с помощью следующего HTTP-заголовка, выводимого вашим веб-сервером.

 Access-Control-Allow-Origin: http://www.example.com

Если вы не можете управлять своими заголовками HTTP, вы не можете использовать CORS. Реализация этого языка зависит от языка/структуры.

Обратите внимание, что вы должны убедиться, что совместимость с браузером, поскольку IE8/9 имеет ограниченную поддержку. Также имейте в виду, что это потенциальный вектор атаки. Он позволяет откликам сторонних сайтов выполнять атаки XSS, если вы безответственно используете данные ответа.

JSONP (возможно)

JSONP - это умный способ передачи и получения данных между серверами путем динамического добавления тега script с помощью src atrribute, равный "yoururl.com?<your parameter data>", на вашу страницу. Это единственный законный способ совершить такой подвиг без веб-прокси (см. Ниже) или апплета (Flash/Java). Однако у него есть свои собственные риски безопасности, если вы не являетесь поставщиком обоих концов запроса. Помните, что JSONP позволяет удаленному серверу выполнять код в вашем контексте, и вы должны быть очень осторожны, кто вы даете эту мощность.

"Vanilla" AJAX (невозможно)

Если вы не используете JSONP для извлечения данных, вы, скорее всего, попытаетесь использовать запрос AJAX для извлечения данных. Запросы AJAX также подчиняются одной и той же политике происхождения. Библиотеки JavaScript (например, jQuery, Prototype, Dojo и т.д.) Не могут обойти эту политику как базовое поведение для Ajax-запроса. Тем не менее, они могут поддерживать JSONP (который помнит сейчас, это не AJAX).

AJAX с веб-прокси (возможно)

Если вы хотите запросить данные с другого сервера, вы можете перенаправить ваш запрос. Ваш основной сервер сайта будет действовать как прокси. Вам нужно будет сделать запрос AJAX на свой собственный сервер, этот код на стороне сервера затем отправит запрос в другой домен, а затем отправит ответ на ваш script с помощью ответа на вызовы AJAX.

Это общий шаблон, и он подробно описан здесь как шаблон веб-прокси и дружественный к приложению Yahoo one здесь (но помните, что это Yahoo специфический, просто возьмите общую идею). Это, однако, зависит от языка на стороне сервера. Общая реализация будет одинаковой, однако код для этого будет зависеть от выбранного вами языка на стороне сервера (PHP, Ruby, Python, C и т.д.). На некоторых языках уже есть библиотеки /modules/etc для поддержки такого шаблона.

Вспышка (возможно, не по умолчанию)

Flash в состоянии по умолчанию не поддерживает запросы перекрестных доменов. Он может быть включен в Flash7 + с файлами междоменной политики, но настоятельно рекомендуется против. Ваш script должен будет взаимодействовать с Flash API, который будет делать запросы и возвращать данные на ваш JavaScript.

Java-апплет (возможно, не по умолчанию)

Java также подвергается одной и той же политике происхождения, но похож на Flash как описанный здесь в своем выпуске.

Различные другие "хаки"

Существуют и другие хаки, но обычно они требуют, чтобы вы контролировали оба конца или имели согласованный стандарт для общения. Например, "window.name" взломает. Я не предлагаю большинство этих методов.

Другие решения

Был задан другой вопрос, подобный этому. В нем описываются несколько других методов, которые я не рассматривал: Способы обхода политики одного и того же происхождения

Лучшие решения

  • CORS - если вы доверяете третьей стороне
  • Веб-прокси - если вы не

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

Ответ 2

У меня была такая же проблема. Попытка получить json с сервера, к которому я не имел доступа (= > нет JSONP).

Я нашел http://benalman.com/projects/php-simple-proxy/ Добавьте php-прокси на ваш сервер и выполните вызов ajax в этот файл. "Любые параметры GET, которые должны быть переданы удалённому ресурсу URL, должны быть указаны в этом параметре".

$.ajax({
   type: 'GET',
   url:'proxy.php?url=http://anyDomain.com?someid=thispage',
   dataType: "json",
   success: function(data){
      // success_fn(data);
   },
   error: function(jqXHR, textStatus, errorThrown) {
      // error_fn(jqXHR, textStatus, errorThrown);
   }
});

где proxy.php(файл от Ben Alman) размещен в вашем домене


Альтернатива (которая, как мне показалось, лучше всего подходит для этого): http://james.padolsey.com/javascript/cross-domain-requests-with-jquery/

Ответ 3

Скорее липким способом сделать это будет то, что я сделал ниже, чтобы включить выполнение кросс-сайта в личном проекте

обратите внимание, что это будет сделано на принимающем сервере, а не на отправке.

    if ((isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') === FALSE)
        die('You shouldn\'t be here');

    header('Access-Control-Allow-Origin: ' . $_SERVER['HTTP_ORIGIN']);
    header('Access-Control-Allow-Methods: POST, GET, OPTIONS');
    header('Access-Control-Max-Age: 1000');
    header('Access-Control-Allow-Headers: Content-Type');

если вы хотите, чтобы он был более безопасным, вы могли бы сделать

    if ((isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') === FALSE)
        die('You shouldn\'t be here');

switch($_SERVER['HTTP_ORIGIN']){
case 'domain.com':
case 'whatever.com':
        header('Access-Control-Allow-Origin: ' . $_SERVER['HTTP_ORIGIN']);
        header('Access-Control-Allow-Methods: POST, GET, OPTIONS');
        header('Access-Control-Max-Age: 1000');
        header('Access-Control-Allow-Headers: Content-Type');
}

Надеюсь, что это помогло мне потребоваться навсегда, чтобы понять, что это за лол.