Аякс кросс доменные вызовы



Я знаю о междоменной политике AJAX.
Поэтому я не могу просто позвонить"http://www.google.com " через HTTP-запрос ajax и отображение
результаты где-то на моем сайте.



Я попробовал его с типом данных "jsonp", что на самом деле будет работать, но я получаю синтаксическую ошибку (очевидно, потому что полученные данные не JSON formated)



есть ли другие возможности для получения / отображения данных из иностранного домена?
iFrames следуют той же политике?

572   11  

11 ответов:

единственный (простой) способ получить междоменные данные с помощью AJAX-это использовать язык на стороне сервера в качестве прокси как Энди Е отметить. Вот небольшой пример как реализовать это с помощью jQuery:

часть jQuery:

$.ajax({
    url: 'proxy.php',
    type: 'POST',
    data: {
        address: 'http://www.google.com'
    },
    success: function(response) {
        // response now contains full HTML of google.com
    }
});

и PHP (прокси.php):

echo file_get_contents($_POST['address']);

просто. Просто знайте, что вы можете или не можете сделать с очищенными данными.

вам нужно будет динамически вставить тег сценария на страницу, которая ссылается на данные. Используя JSONP, вы можете выполнить некоторую функцию обратного вызова при загрузке скрипта.

страница Википедии о JSONP имеет краткий пример; тег скрипта:

<script type="text/javascript" src="http://domain1.com/getjson?jsonp=parseResponse">
</script>

вернет данные JSON, завернутые в вызов parseResponse:

parseResponse({"Name": "Cheeso", "Rank": 7})

(в зависимости от конфигурации getjson скрипт ВКЛ domain1.com)

код для вставки тег динамически будет что-то вроде:

var s = document.createElement("script");
s.src = "http://domain1.com/getjson?jsonp=parseResponse";
s.type = "text/javascript";
document.appendChild(s);

можно использовать YQL выполнить запрос без необходимости размещения собственного прокси-сервера. Я сделал простую функцию, чтобы облегчить выполнение команд:

function RunYQL(command, callback){
     callback_name = "__YQL_callback_"+(new Date()).getTime();
     window[callback_name] = callback;
     a = document.createElement('script');
     a.src = "http://query.yahooapis.com/v1/public/yql?q="
             +escape(command)+"&format=json&callback="+callback_name;
     a.type = "text/javascript";
     document.getElementsByTagName("head")[0].appendChild(a);
}

Если у вас есть jQuery, вы можете использовать $.вместо этого getJSON.

пример может быть такой:

RunYQL('select * from html where url="http://www.google.com/"',
       function(data){/* actions */}
);

к сожалению (или к счастью) нет. Междоменная политика существует по какой-то причине, если бы ее было легко обойти, то она не была бы очень эффективной в качестве меры безопасности. Другие, чем лежит предположение, что единственный вариант-это прокси страницы с помощью собственного сервера.

с iframe они подчиняются одной и той же политике. Конечно, вы можете отображать данные из внешнего домена, вы просто не можете управлять им.

Я использую этот код для междоменного вызова ajax, я надеюсь, что это поможет больше, чем один здесь. Я использую библиотеку прототипов, и вы можете сделать то же самое с JQuery или Dojo или что-нибудь еще:

Шаг 1: создайте новый JS-файл и поместите этот класс внутрь, я назвал его xss_ajax.js

var WSAjax = Class.create ({
    initialize: function (_url, _callback){
        this.url = _url ;
        this.callback = _callback ;
        this.connect () ;
    },
    connect: function (){
        var script_id = null;
        var script = document.createElement('script');
        script.setAttribute('type', 'text/javascript');
        script.setAttribute('src', this.url);
        script.setAttribute('id', 'xss_ajax_script');

        script_id = document.getElementById('xss_ajax_script');
        if(script_id){
            document.getElementsByTagName('head')[0].removeChild(script_id);
        }

        // Insert <script> into DOM
        document.getElementsByTagName('head')[0].appendChild(script);
    },
    process: function (data){
        this.callback(data) ;
    }

}) ;

этот класс создает динамический элемент скрипта, атрибуты src которого предназначены для вашего поставщика данных JSON (JSON-P фактически, поскольку ваш удаленный сервер должен предоставлять данные в этом формате :: call_back_function (//json_data_here) :: поэтому, когда создается тег сценария, ваш JSON будет напрямую вычисляться как функция (мы поговорим о передаче имени метода обратного вызова серверу на Шаге 2), Основная концепция этого заключается в том, что сценарий, подобный элементам img, не связан ограничениями SOP.

Step2: на любой html-странице, где вы хотите вытащить JSON асинхронно (мы называем это AJAJ ~ асинхронный JAvascript + JSON: -) вместо AJAX, которые используют объект XHTTPRequest) do как и ниже

//load Prototype first
//load the file you've created in step1


var xss_crawler = new WSAjax (
     "http://your_json_data_provider_url?callback=xss_crawler.process"
 ,   function (_data){
            // your json data is _data and do whatever you like with it 
        }) ;

вы помните обратный вызов на шаге 1? поэтому мы передаем его на сервер, и он возвращает JSON, встроенный в этот метод, поэтому в нашем случае сервер вернет evalable javascript-код xss_crawler.process (//the_json_data), помните, что xss_crawler является экземпляром класса WSAjax. Код сервера зависит от вас (если он ваш), но большинство поставщиков данных Ajax позволяют вам указать метод обратного вызова в параметрах, как это сделали мы. В Ruby on rails я просто сделал

render :json=>MyModel.all(:limit=>10), :callback => params[:callback],:content_type => "application/json"

и это все, теперь вы можете извлекать данные из другого домена из своих приложений (виджеты, карты и т. д.), Только в формате JSON, не забывайте.

Я надеюсь, что это было полезно, Спасибо за ваше терпение : -), мир и извините за форматирование кода, он не работает хорошо

после проведения некоторых исследований, единственным "решением" этой проблемы является вызов:

if($.browser.mozilla)
   netscape.security.PrivilegeManager.enablePrivilege('UniversalBrowserRead');

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

это работает для браузеров mozilla, в IE

chrome / safari: я не нашел флаг конфигурации для этих браузеров до сих пор.

использование JSONP в качестве типа данных было бы неплохо, но в моем случае я не знаю, нужен ли мне домен для доступа поддерживает данные в этом формате.

еще один выстрел-использовать HTML5 postMessage, который также работает в разных доменах, но я не могу позвольте себе обречь моих пользователей на браузеры HTML5.

Если вы используете php скрипт для получения ответа от удаленного сервера, добавьте эту строку в начале:

header("Access-Control-Allow-Origin: *");

JSONP является лучшим вариантом, на мой взгляд. Попробуйте выяснить, почему вы получаете синтаксическую ошибку - вы уверены, что полученные данные не JSON? Тогда, возможно, вы используете API неправильно как-то.

другой способ, который вы могли бы использовать, но я не думаю, что он применяется в вашем случае, это иметь iFrame на странице, которая src находится в домене, который вы хотите вызвать. Попросите его выполнить вызовы для вас, а затем использовать JS для связи между iFrame и страницей. Это позволит обойти перекрестный домен, но только если вы можете иметь src iFrame в домене, который вы хотите вызвать.

вот простой способ, как вы можете это сделать, не используя ничего необычного или даже JSON.

во-первых, создайте сценарий на стороне сервера для обработки ваших запросов. Что-то вроде http://www.example.com/path/handler.php

вы вызовете его с параметрами, как это: .../дрессировщик.php?param1=12345 & param2=67890

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

document.serverResponse('..all the data, in any format that suits you..');
// Any code could be used instead, because you dont have to encode this data
// All your output will simply be executed as normal javascript

теперь, на стороне клиента скрипт, используйте следующее:

document.serverResponse = function(param){ console.log(param) }

var script = document.createElement('script');
script.src='http://www.example.com/path/handler.php?param1=12345&param2=67890';
document.head.appendChild(script);

единственным ограничением этого подхода является максимальная длина параметров, которые вы можете отправить на сервер. Но, вы всегда можете отправить несколько запросов.

вы можете использовать технологию CORS для настройки обоих серверов (сервер, на котором работает Javascript и внешний сервер API)

https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS

p. s.: ответ https://stackoverflow.com/a/37384641/6505594 также предлагает этот подход, и он открывает внешний сервер API для всех остальных, чтобы вызвать его.

Я столкнулся с той же проблемой в течение 2 дней, и я нашел решение, и это элегантно после того, как погуглил много. Мне нужен XSS Ajax для некоторых клиентов виджетов, которые вытягивают поток данных с веб-сайтов уровней в мое приложение Rails. вот как я это сделал.

Comments

    Ничего не найдено.