AJAX cross domain call

Wiem o AJAX cross-domain policy. So I can 't just call" http://www.google.com " poprzez żądanie HTTP ajax i wyświetlanie wyniki gdzieś na mojej stronie.

Próbowałem z dataType "jsonp", to faktycznie działa, ale dostaję błąd składni (oczywiście dlatego, że odebrane dane nie są sformatowane w JSON)

Czy jest jakaś inna możliwość odbierania / wyświetlania danych z zagranicznej domeny? iFrames przestrzegać tych samych zasad?

Author: jAndy, 2010-04-01

11 answers

Jedynym (łatwym) sposobem uzyskania danych między domenami za pomocą AJAX jest użycie języka po stronie serwera jako proxy, jak zauważył Andy E . Oto mała próbka jak zaimplementować to używając jQuery:

Część jQuery:

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

Oraz PHP (proxy.php):

echo file_get_contents($_POST['address']);
To proste. Po prostu pamiętaj, co możesz lub nie możesz zrobić ze zeskrobanymi danymi.
 66
Author: Tatu Ulmanen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:26:07

Będziesz musiał dynamicznie wstawić znacznik skryptu do strony, która odwołuje się do danych. Używając JSONP, możesz wykonać jakąś funkcję zwrotną po załadowaniu skryptu.

Strona Wikipedii na JSONP ma zwięzły przykład; znacznik skryptu:

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

Zwróci dane JSON zawinięte w wywołaniu do parseResponse:

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

(w zależności od konfiguracji skryptu getjson na domain1.com)

Kod do dynamicznego wstawiania znacznika byłby czymś like:

var s = document.createElement("script");
s.src = "http://domain1.com/getjson?jsonp=parseResponse";
s.type = "text/javascript";
document.appendChild(s);
 18
Author: alunny,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-04-16 22:11:20

Możesz użyć YQL Aby wykonać żądanie bez konieczności hostowania własnego serwera proxy. Zrobiłem prostą funkcję ułatwiającą Uruchamianie poleceń:

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

Jeśli masz jQuery, możesz użyć $.getJSON zamiast.

Próbka może być następująca:

RunYQL('select * from html where url="http://www.google.com/"',
       function(data){/* actions */}
);
 16
Author: Alexandre Vicente,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-09-10 03:58:39

Niestety (lub na szczęście) nie. Polityka między domenami istnieje nie bez powodu, gdyby łatwo było ją obejść, nie byłaby zbyt skuteczna jako środek bezpieczeństwa. Poza JSONP, jedyną opcją jest proxy stron przy użyciu własnego serwera .

Z ramką iframe, podlegają one tej samej polityce. Oczywiście możesz wyświetlać dane z zewnętrznej domeny, po prostu nie możesz nimi manipulować.

 11
Author: Andy E,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-04-01 08:22:41

Używam tego kodu do cross domain Ajax call, mam nadzieję, że pomoże więcej niż jeden tutaj. Używam Biblioteki Prototype i możesz zrobić to samo z JQuery lub Dojo lub czymkolwiek innym:

Krok 1: Utwórz nowy plik js i umieść tę klasę w środku, nazwałem ją 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) ;
    }

}) ;

Ta klasa tworzy dynamiczny element skryptu, którego atrybuty src są skierowane do Twojego dostawcy danych JSON (JSON-P w rzeczywistości, ponieważ twój odległy serwer musi dostarczyć dane w tym formacie :: call_back_function (//json_data_here):: więc kiedy tag skryptu jest tworzony Twój JSON będzie bezpośrednio evaled jako funkcja (porozmawiamy o przekazaniu nazwy metody callback na serwer w Kroku 2), główną koncepcją za tym jest to, że skrypt jak elementy img nie są objęte ograniczeniami SOP.

Krok 2: na dowolnej stronie html, na której chcesz asynchronicznie wyciągnąć JSON (nazywamy to AJAJ ~ Asynchronous JAvascript + JSON :-) zamiast AJAX, który używa obiektu XHTTPRequest) zrób jak poniżej

//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 
        }) ;
Pamiętasz oddzwonienie na pierwszym kroku? więc przekazujemy go do serwera i zwróci JSON osadzony w tej metodzie, więc w naszym przypadku serwer zwróci evalable javascript code xss_crawler.process(//the_json_data), pamiętaj, że xss_crawler jest instancją klasy WSAjax. Kod serwera zależy od Ciebie( jeśli jest Twój), ale większość dostawców danych Ajax pozwala określić metodę wywołania zwrotnego w parametrach, tak jak my. W Ruby on rails właśnie zrobiłem
render :json=>MyModel.all(:limit=>10), :callback => params[:callback],:content_type => "application/json"

Oraz to wszystko, możesz teraz pobierać dane z innej domeny z aplikacji (Widżety, mapy itp.), tylko w formacie JSON, nie zapomnij.

Mam nadzieję, że to było pomocne, dzięki za cierpliwość: -), spokój i przepraszam za formatowanie kodu, nie działa dobrze

 4
Author: R Francky,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-11 17:30:12

Po przeprowadzeniu pewnych badań, jedynym "rozwiązaniem" tego problemu jest wywołanie:

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

To zapyta użytkownika, czy pozwala na kontynuowanie witryny. Po tym, jak to potwierdził, wszystkie wywołania ajax niezależnie od typu danych będą wykonywane.

Działa to w przeglądarkach Mozilli, w IE

Chrome / safari: nie znalazłem flagi konfiguracyjnej dla tych przeglądarek, więc daleko.

Używanie JSONP jako datatype byłoby miłe, ale w moim przypadku nie wiem, czy domena jest mi potrzebna aby uzyskać dostęp do danych w tym formacie.

Kolejnym ujęciem jest użycie HTML5 postMessage, który działa również między domenami, ale nie mogę pozwolić sobie na doom moich użytkowników do przeglądarek HTML5.

 4
Author: jAndy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-09-28 19:56:11

Jeśli używasz skryptu php, aby uzyskać odpowiedź ze zdalnego serwera, dodaj tę linię na początku:

header("Access-Control-Allow-Origin: *");
 3
Author: akadi81,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-23 07:09:20

JSONP to moim zdaniem najlepsza opcja. Spróbuj dowiedzieć się, dlaczego dostajesz błąd składni - czy na pewno odebrane dane nie są JSON? To może źle używasz API.

Innym sposobem, który możesz użyć, ale nie sądzę, że ma to zastosowanie w Twoim przypadku, jest posiadanie iFrame na stronie, która src jest w domenie, którą chcesz wywołać. Niech zrobi to za Ciebie, a następnie użyj JS, aby komunikować się między ramką iFrame a stroną. Spowoduje to ominięcie cross domeny, ale tylko wtedy, gdy możesz miej src iFrame w domenie, do której chcesz zadzwonić.

 2
Author: Nir,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-04-01 08:15:58

Oto prosty sposób na to, jak możesz to zrobić, bez konieczności używania czegokolwiek wymyślnego, ani nawet JSONA.

Najpierw Utwórz skrypt po stronie serwera, który obsłuży Twoje żądania. Coś jak http://www.example.com/path/handler.php

Wywołasz go z parametrami, jak to:.../ align = "left" / php?param1=12345&param2 = 67890

Wewnątrz niego, po przetworzeniu otrzymanych danych, wyjście :

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

Teraz, w skrypcie po stronie klienta, użyj "po": {]}

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

Jedynym ograniczeniem tego podejścia jest maksymalna długość parametrów, które można wysłać na serwer. Ale zawsze możesz wysłać wiele żądań.

 1
Author: AlexTR,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-06-08 04:53:29

Możesz użyć technologii CORS do skonfigurowania obu serwerów (serwera, na którym działa Javascript i zewnętrznego serwera API)

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

P. s.: odpowiedź https://stackoverflow.com/a/37384641/6505594 sugeruje również takie podejście i otwiera zewnętrzny serwer API dla wszystkich innych, aby go wywołać.

 0
Author: morhook,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-31 19:23:26

Miałem ten sam problem w ciągu 2 dni i znalazłem rozwiązanie. jest eleganckie po częstym googlowaniu. Potrzebowałem XSS Ajax dla niektórych klientów widgetów, które ciągną strumień danych ze stron warstwowych do mojej aplikacji Rails. Tak zrobiłem.

 -3
Author: R Francky,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-08-27 14:36:58