wake-up-neo.net

AJAX Domainübergreifender Anruf

Ich kenne die domänenübergreifende Richtlinie AJAX . Ich kann also nicht einfach " http://www.google.com " über eine ajax-HTTP-Anforderung aufrufen und die Ergebnisse anzeigen .__ irgendwo auf meiner Website.

Ich habe es mit Datentyp "jsonp" ausprobiert, das würde tatsächlich funktionieren, aber ich erhalte einen Syntaxfehler (offensichtlich, weil die empfangenen Daten nicht JSON-formatiert sind)

Gibt es eine andere Möglichkeit, Daten von einer fremden Domäne zu empfangen/anzuzeigen? I Frames folgen denselben Richtlinien?

64
jAndy

Die einzige (einfache) Möglichkeit, domänenübergreifende Daten mit AJAX abzurufen, ist die Verwendung einer serverseitigen Sprache als Proxy, wie in Andy E angegeben. Hier ein kleines Beispiel, wie man das mit jQuery implementiert:

Der jQuery-Teil:

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

Und das PHP (proxy.php):

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

So einfach ist das. Seien Sie sich nur bewusst, was Sie mit den gescrapten Daten tun können oder nicht.

65
Tatu Ulmanen

Sie müssen ein Skripttag dynamisch in die Seite einfügen, die auf die Daten verweist. Mit JSONP können Sie einige Callback-Funktionen ausführen, wenn das Skript geladen wurde.

Die Wikipedia-Seite zu JSONP hat ein kurzes Beispiel; das Skript-Tag:

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

würde die JSON-Daten in einem Aufruf an parseResponse zurückgeben:

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

(abhängig von der Konfiguration des getjson-Skripts auf domain1.com)

Der Code zum dynamischen Einfügen des Tags würde etwa so aussehen:

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

Sie können YQL verwenden, um die Anforderung auszuführen, ohne einen eigenen Proxy zu hosten. Ich habe eine einfache Funktion erstellt, um das Ausführen von Befehlen zu erleichtern:

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

Wenn Sie jQuery haben, können Sie stattdessen $ .getJSON verwenden.

Ein Beispiel kann dies sein:

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

Leider (oder zum Glück) nicht. Die domänenübergreifende Richtlinie gibt es aus einem bestimmten Grund. Wenn sie leicht zu umgehen wäre, wäre sie als Sicherheitsmaßnahme nicht sehr effektiv. Abgesehen von JSONP besteht die einzige Möglichkeit darin, die Seiten mit Ihrem eigenen Server zu vertreten.

Bei einem iframe unterliegen sie derselben Richtlinie. Natürlich können Sie die Daten von einer externen Domäne anzeigen, Sie können sie einfach nicht bearbeiten.

11
Andy E

Ich verwende diesen Code für einen domänenübergreifenden Ajax-Aufruf. Ich hoffe, es hilft hier mehr als einem. Ich verwende die Prototypbibliothek, und Sie können dasselbe mit JQuery oder Dojo oder etwas anderem machen:

Schritt 1: Erstellen Sie eine neue js-Datei und fügen Sie diese Klasse ein. Ich habe sie xss_ajax.js genannt

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

}) ;

Diese Klasse erstellt ein dynamisches Skriptelement, das von src-Attributen auf Ihren JSON-Datenprovider abzielt (JSON-P, da Ihr entfernter Server die Daten in diesem Format bereitstellen muss: call_back_function (// json_data_here) ::. Wenn also das Script-Tag erstellt wird JSON wird direkt als Funktion ausgewertet (in Schritt 2 wird der Name der Callback-Methode an den Server übergeben). Das Hauptkonzept dahinter ist, dass Skripts wie img-Elemente nicht von den SOP -Einschränkungen betroffen sind.

Schritt 2: Auf jeder HTML-Seite, auf der Sie den JSON asynchron ziehen möchten (wir nennen dieses AJAJ ~ Asynchronous JAvascript + JSON :-) anstelle von AJAX, die das Objekt XHTTPRequest verwenden), wie unten beschrieben

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

Erinnern Sie sich an den Rückruf in Schritt 1? Wir übergeben ihn also an den Server und geben die in diese Methode eingebettete JSON zurück. In diesem Fall gibt der Server einen auswertbaren Javascript-Code xss_crawler.process (// the_json_data) zurück. Denken Sie daran, dass xss_crawler eine Instanz der WSAjax-Klasse ist. Der Server-Code hängt von Ihnen ab (wenn es Ihnen gehört), aber bei den meisten Ajax-Datenprovidern können Sie die Callback-Methode in Parametern angeben, wie wir es getan haben. In Ruby on Rails habe ich es gerade getan

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

und das ist alles, Sie können jetzt Daten aus einer anderen Domäne aus Ihren Apps (Widgets, Karten usw.) abrufen, nur im JSON-Format. Vergessen Sie nicht.

Ich hoffe es war hilfreich, danke für Ihre Geduld :-), Ruhe und Entschuldigung für die Code-Formatierung, es funktioniert nicht gut

4
R Francky

nach einigen Recherchen lautet die einzige "Lösung" für dieses Problem:

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

dadurch wird ein Benutzer gefragt, ob er eine Website weiter betreiben darf. Nachdem er dies bestätigt hat, werden alle Ajax-Aufrufe unabhängig von ihrem Datentyp ausgeführt.

Dies funktioniert für Mozilla-Browser. In IE <8 muss ein Benutzer einen domänenübergreifenden Aufruf zulassen Auf ähnliche Weise müssen einige Versionen innerhalb der Browseroptionen konfiguriert werden.

chrome/safari: Ich habe für diese Browser bisher kein Konfigurationsflag gefunden.

jSONP als Datentyp zu verwenden, wäre Nizza, aber in meinem Fall weiß ich nicht, ob eine Domäne, die ich benötige, zur Verfügung steht. Zum Zugriff auf Daten in diesem Format.

Eine andere Einstellung ist die Verwendung von HTML5 postMessage, das auch domänenübergreifend funktioniert, aber ich kann es mir nicht leisten, meine Benutzer zu HTML5-Browsern zu verdammen.

4
jAndy

Wenn Sie ein PHP-Skript verwenden, um die Antwort vom Remote-Server zu erhalten, fügen Sie diese Zeile am Anfang hinzu:

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

JSONP ist meiner Meinung nach die beste Option. Versuchen Sie herauszufinden, warum Sie den Syntaxfehler erhalten. Sind Sie sicher, dass die empfangenen Daten nicht JSON sind? Dann benutzt du vielleicht die API irgendwie falsch.

Eine andere Möglichkeit, die Sie verwenden könnten, aber ich glaube nicht, dass dies in Ihrem Fall zutrifft, ist ein iFrame auf der Seite, den src in der Domäne enthält, die Sie anrufen möchten. Lassen Sie es die Anrufe für Sie erledigen und verwenden Sie dann JS, um zwischen dem iFrame und der Seite zu kommunizieren. Dadurch wird die domänenübergreifende Domäne umgangen, jedoch nur, wenn Sie die src des iFrame in der Domäne haben können, die Sie anrufen möchten.

2
Nir

Hier ist eine einfache Möglichkeit, wie Sie dies tun können, ohne irgendetwas oder gar JSON verwenden zu müssen.

Erstellen Sie zunächst ein serverseitiges Skript, um Ihre Anforderungen zu bearbeiten. So etwas wie http://www.example.com/path/handler.php

Sie werden es mit Parametern wie dem folgenden aufrufen: .../handler.php? Param1 = 12345 & param2 = 67890

Nach der Verarbeitung der empfangenen Daten output:

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

Verwenden Sie nun im clientseitigen Skript Folgendes:

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

Die einzige Grenze dieses Ansatzes ist die maximale Länge der Parameter, die Sie an den Server senden können. Sie können jedoch immer mehrere Anfragen senden.

1
AlexTR

Sie können die Technologie CORS verwenden, um beide Server (den Server, auf dem das Javascript ausgeführt wird, und den externen API-Server) zu konfigurieren.

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

p .: die Antwort https://stackoverflow.com/a/37384641/6505594 schlägt ebenfalls diesen Ansatz vor und öffnet den externen API-Server für alle, die ihn anrufen.

0
morhook