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
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).
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 .
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.
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.
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.
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);
}
});
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:
"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."
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 .
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.
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.
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
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.
Ich kenne 3 Möglichkeiten, um Ihr Problem zu lösen:
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>
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.
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 }
});
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.