Перекрестный вызов AJAX

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

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

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

Ответ 1

Единственный (простой) способ получить междоменные данные с использованием AJAX - использовать серверный язык в качестве прокси-сервера в качестве Andy E. Вот небольшой пример, как реализовать это с помощью 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 (proxy.php):

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

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

Ответ 2

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

На странице wikipedia JSONP приведен краткий пример; тег script:

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

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

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

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

Код для динамического вставки тега будет выглядеть примерно так:

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

Ответ 3

Вы можете использовать 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 */}
);

Ответ 4

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

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

Ответ 5

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

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

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

Это работает для браузеров Mozilla, в IE < 8, пользователь должен разрешить вызов перекрестного домена аналогичным образом, некоторая версия должна быть настроена в настройках браузера.

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

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

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

Ответ 6

Я использую этот код для перекрестного домена ajax-звонка, надеюсь, что он поможет более чем одному здесь. Я использую библиотеку Prototype, и вы можете сделать то же самое с 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) ;
    }

}) ;

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

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

//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, внедренный в этот метод, поэтому в нашем случае сервер вернет код 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.

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

Ответ 7

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

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

Ответ 8

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

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

Ответ 9

Вот простой способ, как вы можете это сделать, без использования каких-либо фантазий или даже JSON.

Сначала создайте серверную часть script для обработки ваших запросов. Что-то вроде http://www.example.com/path/handler.php

Вы будете называть его параметрами, например:.../handler.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

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

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);

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

Ответ 10

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

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

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

Ответ 11

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