it-swarm.com.de

jQuery AJAX domänenübergreifend

Hier sind zwei Seiten, test.php und testserver.php.

test.php

<script src="scripts/jq.js" type="text/javascript"></script>
<script>
    $(function() {
        $.ajax({url:"testserver.php",
            success:function() {
                alert("Success");
            },
            error:function() {
                alert("Error");
            },
            dataType:"json",
            type:"get"
        }
    )})
</script>

testserver.php

<?php
$arr = array("element1",
             "element2",
             array("element31","element32"));
$arr['name'] = "response";
echo json_encode($arr);
?>

Nun mein Problem: Wenn sich beide Dateien auf demselben Server befinden (entweder localhost oder web server), funktioniert es und alert("Success") wird aufgerufen; Befindet es sich auf verschiedenen Servern, d. H. Testserver.php auf dem Webserver und test.php auf localhost, funktioniert es nicht und alert("Error") wird ausgeführt. Auch wenn die URL in Ajax in http://domain.com/path/to/file/testserver.php geändert wird

461
Firose Hussain

Verwenden Sie JSONP .

jQuery:

$.ajax({
     url:"testserver.php",
     dataType: 'jsonp', // Notice! JSONP <-- P (lowercase)
     success:function(json){
         // do stuff with json (in this case an array)
         alert("Success");
     },
     error:function(){
         alert("Error");
     }      
});

PHP:

<?php
$arr = array("element1","element2",array("element31","element32"));
$arr['name'] = "response";
echo $_GET['callback']."(".json_encode($arr).");";
?>

Das Echo könnte falsch sein, es ist schon eine Weile her, dass ich PHP verwendet habe. In jedem Fall müssen Sie callbackName('jsonString') ausgeben und die Anführungszeichen beachten. jQuery übergibt einen eigenen Rückrufnamen, den Sie also von den GET-Parametern abrufen müssen.

Und wie Stefan Kendall geschrieben hat, ist $. GetJSON () eine Kurzform, aber dann müssen Sie 'callback=?' an die URL als GET-Parameter anhängen (ja, Wert ist ?, jQuery ersetzt dies mit einer eigenen generierten Callback-Methode).

407
BGerrissen

JSONP ist eine gute Option, aber es gibt einen einfacheren Weg. Sie können einfach den Header Access-Control-Allow-Origin auf Ihrem Server festlegen. Wenn Sie * festlegen, werden domänenübergreifende AJAX Anforderungen von jeder Domäne akzeptiert. ( https://developer.mozilla.org/en/http_access_control )

Die Methode dazu ist natürlich von Sprache zu Sprache unterschiedlich. Hier ist es in Rails:

class HelloController < ApplicationController
  def say_hello
    headers['Access-Control-Allow-Origin'] = "*"
    render text: "hello!"
  end
end

In diesem Beispiel akzeptiert die Aktion say_hello AJAX Anforderungen von einer beliebigen Domain und gibt die Antwort "Hallo!" Zurück.

Hier ist ein Beispiel für die Header, die möglicherweise zurückgegeben werden:

HTTP/1.1 200 OK 
Access-Control-Allow-Origin: *
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Content-Type: text/html; charset=utf-8
X-Ua-Compatible: IE=Edge
Etag: "c4ca4238a0b923820dcc509a6f75849b"
X-Runtime: 0.913606
Content-Length: 6
Server: WEBrick/1.3.1 (Ruby/1.9.2/2011-07-09)
Date: Thu, 01 Mar 2012 20:44:28 GMT
Connection: Keep-Alive

So einfach es ist, es gibt einige Browser-Einschränkungen. Siehe http://caniuse.com/#feat=cors .

200
joshuarh

Sie können dies über den HTTP-Header steuern, indem Sie Access-Control-Allow-Origin hinzufügen. Wenn Sie * festlegen, werden domänenübergreifende AJAX Anfragen von jeder Domäne akzeptiert.

Mit PHP ist es ganz einfach, fügen Sie einfach die folgende Zeile in das Skript ein, auf das Sie außerhalb Ihrer Domain zugreifen möchten:

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

Vergessen Sie nicht, das Modul mod_headers in httpd.conf zu aktivieren.

30
Adorjan Princz

Sie müssen sich Same Origin Policy ansehen:

In der Datenverarbeitung ist dieselbe Origin-Richtlinie ein wichtiges Sicherheitskonzept für eine Reihe browserseitiger Programmiersprachen wie JavaScript. Die Richtlinie ermöglicht es Skripten, die auf Seiten ausgeführt werden, die von derselben Site stammen, ohne bestimmte Einschränkungen auf die Methoden und Eigenschaften der anderen zuzugreifen, verhindert jedoch den Zugriff auf die meisten Methoden und Eigenschaften über Seiten auf verschiedenen Sites hinweg.

Damit Sie Daten abrufen können, müssen folgende Voraussetzungen erfüllt sein:

Gleiches Protokoll und Host

Sie müssen JSONP implementieren, um das Problem zu umgehen.

19
Sarfraz

Ich musste die Webseite von der lokalen Festplatte "file: /// C: /test/htmlpage.html" laden, die URL "http: //localhost/getxml.php" aufrufen und dies in den Browsern IE8 + und Firefox12 + mit jQuery v1 tun .7.2 lib zur Minimierung des Boilerplate-Codes. Nachdem ich Dutzende Artikel gelesen hatte, fand ich es endlich heraus. Hier ist meine Zusammenfassung.

  • serverskript (.php, .jsp, ...) muss http-Antwortheader zurückgeben Access-Control-Allow-Origin: *
  • vor der Verwendung von jQuery ajax setzen Sie dieses Flag in Javascript: jQuery.support.cors = true;
  • sie können das Flag einmal oder jedes Mal setzen, bevor Sie die jQuery-Ajax-Funktion verwenden
  • jetzt kann ich XML-Dokumente in IE und Firefox lesen. Andere Browser habe ich nicht getestet.
  • antwortdokument kann normal/text, xml, json oder irgendetwas anderes sein

Hier ist ein Beispiel für einen jQuery-Ajax-Aufruf mit einigen Debug-Sysouts.

jQuery.support.cors = true;
$.ajax({
    url: "http://localhost/getxml.php",
    data: { "id":"doc1", "rows":"100" },
    type: "GET",
    timeout: 30000,
    dataType: "text", // "xml", "json"
    success: function(data) {
        // show text reply as-is (debug)
        alert(data);

        // show xml field values (debug)
        //alert( $(data).find("title").text() );

        // loop JSON array (debug)
        //var str="";
        //$.each(data.items, function(i,item) {
        //  str += item.title + "\n";
        //});
        //alert(str);
    },
    error: function(jqXHR, textStatus, ex) {
        alert(textStatus + "," + ex + "," + jqXHR.responseText);
    }
});
16
Whome

Es ist richtig, dass die Same-Origin-Richtlinie verhindert, dass JavaScript domänenübergreifende Anforderungen stellt. Die CORS-Spezifikation ermöglicht jedoch nur die Art von API-Zugriff, nach der Sie suchen, und wird vom aktuellen Stapel der wichtigsten Browser unterstützt.

So aktivieren Sie die herkunftsübergreifende Ressourcenfreigabe für Client und Server:

http://enable-cors.org/

"Cross-Origin Resource Sharing (CORS) ist eine Spezifikation, die einen wirklich offenen Zugriff über Domänengrenzen hinweg ermöglicht. Wenn Sie öffentlichen Inhalt bereitstellen, sollten Sie CORS verwenden, um ihn für den universellen Zugriff auf JavaScript/Browser zu öffnen."

10
Jason

Dies ist möglich, aber Sie müssen JSONP und nicht JSON verwenden. Stefans Link wies Sie in die richtige Richtung. Die Seite jQuery AJAX enthält weitere Informationen zu JSONP.

Remy Sharp hat ein ausführliches Beispiel mit PHP .

9
Paul Schreiber

Ich benutze den Apache-Server, also habe ich das mod_proxy-Modul verwendet. Module aktivieren:

LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so

Dann füge hinzu:

ProxyPass /your-proxy-url/ http://service-url:serviceport/

Schließlich übergeben Sie die Proxy-URL an Ihr Skript.

9
zenio

Durch die Browsersicherheit wird verhindert, dass ein Ajax-Aufruf von einer in einer Domain gehosteten Seite zu einer in einer anderen Domain gehosteten Seite erfolgt. Dies wird als " same-Origin policy " bezeichnet.

8
Jacob Mattison

Es gibt einige Beispiele für die Verwendung von JSONP, die die Fehlerbehandlung umfassen.

Beachten Sie jedoch, dass das Fehlerereignis bei Verwendung von JSONP nicht ausgelöst wird! Siehe: http://api.jquery.com/jQuery.ajax/ oder jQuery ajax request using jsonp error

5
BillyTom

Aus den Jquery-Dokumenten ( link ):

  • Aufgrund von Browser-Sicherheitsbeschränkungen unterliegen die meisten "Ajax" -Anfragen derselben Origin-Richtlinie. Die Anforderung kann keine Daten von einer anderen Domäne, Unterdomäne oder einem anderen Protokoll abrufen.

  • Skript- und JSONP-Anforderungen unterliegen nicht denselben Einschränkungen der Origin-Richtlinie.

Daher würde ich davon ausgehen, dass Sie für die Anforderung jsonp verwenden müssen. Aber habe das nicht selbst ausprobiert.

4
William Clemens

Ich kenne 3 Möglichkeiten, um Ihr Problem zu lösen:

  1. Erstens, wenn Sie Zugriff auf beide Domänen haben, können Sie den Zugriff für alle anderen Domänen über Folgendes zulassen:

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

    oder einfach eine Domain, indem Sie den folgenden Code zur .htaccess-Datei hinzufügen:

    <FilesMatch "\.(ttf|otf|eot|woff)$"> <IfModule mod_headers.c> SetEnvIf Origin "http(s)?://(www\.)?(google.com|staging.google.com|development.google.com|otherdomain.net|dev02.otherdomain.net)$" AccessControlAllowOrigin=$0 Header add Access-Control-Allow-Origin %{AccessControlAllowOrigin}e env=AccessControlAllowOrigin </IfModule> </FilesMatch>

  2. sie können eine Ajax-Anfrage für eine PHP-Datei auf Ihrem Server haben und mit dieser PHP-Datei Anfragen an eine andere Domain bearbeiten.

  3. sie können jsonp verwenden, da es keine Erlaubnis benötigt. dazu kannst du unsere freundin @BGerrissen antworten lesen.
1
Ali_Hr

es funktioniert, alles was Sie brauchen:

PHP:

header('Access-Control-Allow-Origin: http://www.example.com');
header("Access-Control-Allow-Credentials: true");
header('Access-Control-Allow-Methods: GET, PUT, POST, DELETE, OPTIONS');

JS (jQuery Ajax):

var getWBody = $.ajax({ cache: false,
        url: URL,
        dataType : 'json',
        type: 'GET',
        xhrFields: { withCredentials: true }
});
0

Bei Microsoft Azure ist das etwas anders.

Azure verfügt über eine spezielle CORS-Einstellung, die festgelegt werden muss. Es ist im Grunde das Gleiche hinter den Kulissen, aber das einfache Setzen der Überschriften, die Joshuarh erwähnt, wird nicht funktionieren. Die Azure-Dokumentation zum Aktivieren domänenübergreifender Funktionen finden Sie hier:

https://docs.Microsoft.com/en-us/Azure/app-service-api/app-service-api-cors-consume-javascript

Ich habe ein paar Stunden damit herumgespielt, bevor mir klar wurde, dass meine Hosting-Plattform diese spezielle Einstellung hat.

0
Josh Schultz