Ich entwickle eine Seite, die Bilder von Flickr und Panoramio über die AJAX -Unterstützung von jQuery abruft.
Die Flickr-Seite funktioniert einwandfrei, aber wenn ich in Panoramio $.get(url, callback)
versuche, wird in der Chrome-Konsole ein Fehler angezeigt:
XMLHttpRequest kann nicht laden http: //www.panoramio.com/wapi/data/get_photos? V = 1 & key = dummykey & tag = test & offset = 0 & length = 20 & callback = processImages & minx = -30 & miny = 0 & maxx = 0 & maxy = 150 . Origin null ist von Access-Control-Allow-Origin nicht erlaubt.
Wenn ich diese URL direkt von einem Browser aus abfrage, funktioniert sie einwandfrei. Was ist los, und kann ich das umgehen? Verfasse ich meine Abfrage falsch oder behindert Panoramio das, was ich versuche?
Google hat in der - Fehlermeldung keine nützlichen Übereinstimmungen gefunden.
EDIT
Hier ist ein Beispielcode, der das Problem zeigt:
$().ready(function () {
var url = 'http://www.panoramio.com/wapi/data/get_photos?v=1&key=dummykey&tag=test&offset=0&length=20&callback=processImages&minx=-30&miny=0&maxx=0&maxy=150';
$.get(url, function (jsonp) {
var processImages = function (data) {
alert('ok');
};
eval(jsonp);
});
});
Sie können das Beispiel online ausführen .
EDIT 2
Vielen Dank an Darin für seine Hilfe. DER OBIGE CODE IS FALSCH. Verwenden Sie stattdessen Folgendes:
$().ready(function () {
var url = 'http://www.panoramio.com/wapi/data/get_photos?v=1&key=dummykey&tag=test&offset=0&length=20&minx=-30&miny=0&maxx=0&maxy=150&callback=?';
$.get(url, function (data) {
// can use 'data' in here...
});
});
Soweit ich das beurteilen kann, hatten Sie zwei Probleme:
Sie haben Ihrem $.get
keinen "jsonp" -Typ-Bezeichner übergeben, daher wurde ein gewöhnlicher XMLHttpRequest verwendet. Ihr Browser unterstützte jedoch CORS (Cross-Origin Resource Sharing), um domänenübergreifendes XMLHttpRequest zuzulassen, wenn der Server dies bestätigt hat. Hier kam der Header Access-Control-Allow-Origin
ins Spiel.
Ich glaube, Sie haben erwähnt, dass Sie es von einer Datei ausführen: // URL. CORS-Header können auf zwei Arten signalisieren, dass eine domänenübergreifende XHR in Ordnung ist. Einer ist, Access-Control-Allow-Origin: *
zu senden (was, wenn Sie Flickr über $.get
erreicht haben, müssen sie getan haben), während der andere den Inhalt des Headers Origin
zurückzusenden war. file://
URLs erzeugen jedoch eine Null Origin
, die nicht per Echo-Back autorisiert werden kann.
Das erste Problem wurde auf Umwegen gelöst, nachdem Darin vorgeschlagen hatte, $.getJSON
zu verwenden. Es ist ein wenig magisch, den Anforderungstyp von "json" in "jsonp" zu ändern, wenn die Teilzeichenfolge callback=?
in der URL angezeigt wird.
Das löste den zweiten Fehler, indem nicht mehr versucht wurde, eine CORS-Anforderung von einer file://
-URL auszuführen.
Zur Verdeutlichung für andere Personen finden Sie hier die einfachen Anweisungen zur Fehlerbehebung:
$.get
und setzen dataType
auf jsonp
.$.getJSON
und haben callback=?
in die URL aufgenommen.http://
testen. Skripte, die über file://
ausgeführt werden, unterstützen CORS nur eingeschränkt.Sie müssen in Ihrem aufgerufenen Skript möglicherweise einen HEADER hinzufügen. Hier ist, was ich in PHP tun musste:
header('Access-Control-Allow-Origin: *');
Weitere Details in domänenübergreifend AJAX ou services WEB (auf Französisch).
Für ein einfaches HTML-Projekt:
cd project
python -m SimpleHTTPServer 8000
Dann durchsuchen Sie Ihre Datei.
Funktioniert für mich unter Google Chrome v5.0.375.127 (ich erhalte die Warnung):
$.get('http://www.panoramio.com/wapi/data/get_photos?v=1&key=dummykey&tag=test&offset=0&length=20&callback=?&minx=-30&miny=0&maxx=0&maxy=150',
function(json) {
alert(json.photos[1].photoUrl);
});
Außerdem würde ich empfehlen, stattdessen die $.getJSON()
-Methode zu verwenden, da die vorherige in IE8 nicht funktioniert (zumindest auf meinem Computer):
$.getJSON('http://www.panoramio.com/wapi/data/get_photos?v=1&key=dummykey&tag=test&offset=0&length=20&callback=?&minx=-30&miny=0&maxx=0&maxy=150',
function(json) {
alert(json.photos[1].photoUrl);
});
Sie können es versuchen online von hier .
AKTUALISIEREN:
Jetzt, da Sie Ihren Code gezeigt haben, kann ich das Problem damit sehen. Sie haben sowohl eine anonyme Funktion als auch eine Inline-Funktion, aber beide werden als processImages
bezeichnet. So funktioniert die JSONP-Unterstützung von jQuery. Beachten Sie, wie ich den callback=?
definiere, damit Sie eine anonyme Funktion verwenden können. Sie können mehr lesen darüber in der Dokumentation .
Eine weitere Bemerkung ist, dass Sie eval nicht nennen sollten. Der an Ihre anonyme Funktion übergebene Parameter wird bereits von jQuery in JSON analysiert.
Verwenden Sie die JSONP-Schnittstelle (JSON Padding), solange der angeforderte Server das JSON-Datenformat unterstützt. Sie können damit externe Domain-Anfragen ohne Proxy-Server oder ausgefallene Header-Inhalte stellen.
Es ist die gleiche Origin-Richtlinie , Sie müssen eine JSON-P-Schnittstelle oder einen Proxy verwenden, der auf demselben Host ausgeführt wird.
Wir haben es über die http.conf
-Datei verwaltet (den HTTP-Dienst bearbeitet und dann neu gestartet):
<Directory "/home/the directory_where_your_serverside_pages_is">
Header set Access-Control-Allow-Origin "*"
AllowOverride all
Order allow,deny
Allow from all
</Directory>
Im Header set Access-Control-Allow-Origin "*"
können Sie eine genaue URL angeben.
Wenn Sie lokale Tests durchführen oder die Datei von etwas wie file://
aufrufen, müssen Sie die Browsersicherheit deaktivieren.
Auf MAC: open -a Google\ Chrome --args --disable-web-security
In meinem Fall hat derselbe Code in Firefox einwandfrei funktioniert, aber nicht in Google Chrome. Die JavaScript-Konsole von Google Chrome sagte:
XMLHttpRequest cannot load http://www.xyz.com/getZipInfo.php?zip=11234.
Origin http://xyz.com is not allowed by Access-Control-Allow-Origin.
Refused to get unsafe header "X-JSON"
Ich musste den www-Teil der Ajax-URL löschen, damit er richtig mit der Origin-URL übereinstimmt, und es funktionierte dann einwandfrei.
Nicht alle Server unterstützen jsonp. Der Server muss die Rückruffunktion in den Ergebnissen festlegen. Ich verwende dies, um JSON-Antworten von Websites zu erhalten, die reinen JSON-Code zurückgeben, aber JSONP nicht unterstützen:
function AjaxFeed(){
return $.ajax({
url: 'http://somesite.com/somejsonfile.php',
data: {something: true},
dataType: 'jsonp',
/* Very important */
contentType: 'application/json',
});
}
function GetData() {
AjaxFeed()
/* Everything worked okay. Hooray */
.done(function(data){
return data;
})
/* Okay jQuery is stupid manually fix things */
.fail(function(jqXHR) {
/* Build HTML and update */
var data = jQuery.parseJSON(jqXHR.responseText);
return data;
});
}
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.
Als letzte Anmerkung das Mozilla-Dokumentation sagt ausdrücklich das
Das obige Beispiel würde fehlschlagen, wenn der Header wie folgt mit einem Platzhalter versehen wäre: Access-Control-Allow-Origin: *. Seit dem Access-Control-Allow-Origin explizit Erwähnungen http: //foo.example , der Inhalt, der die Anmeldeinformationen kennt, wird an den aufrufenden Webinhalt zurückgegeben.
Infolgedessen ist es nicht einfach eine schlechte Praxis, '*' zu verwenden. Funktioniert einfach nicht :)
Für PHP - das funktioniert für mich auf Chrome, Safari und Firefox
header('Access-Control-Allow-Origin: null');
mit axios rufen sie php live services mit file: // auf
Ich habe auch den gleichen Fehler in Chrome erhalten (ich habe keine anderen Browser getestet). Dies lag an der Tatsache, dass ich auf domain.com anstatt auf www.domain.com navigierte. Ein bisschen seltsam, aber ich könnte das Problem lösen, indem ich die folgenden Zeilen zu .htaccess hinzufüge. Domain.com wird auf www.domain.com umgeleitet und das Problem wurde behoben. Ich bin ein fauler Webbesucher, also schreibe ich fast nie das WWW, aber anscheinend ist es in einigen Fällen erforderlich.
RewriteEngine on
RewriteCond %{HTTP_Host} ^domain\.com$ [NC]
RewriteRule ^(.*)$ http://www.domain.com/$1 [R=301,L]
Stellen Sie sicher, dass Sie die neueste Version von JQuery verwenden. Wir hatten diesen Fehler für JQuery 1.10.2 und der Fehler wurde behoben, nachdem JQuery 1.11.1 verwendet wurde
Es gibt ein kleines Problem in der Lösung von CodeGroover oben . Wenn Sie eine Datei ändern, müssen Sie den Server neu starten, um die aktualisierte Datei tatsächlich zu verwenden (zumindest in meinem Fall).
Nach einigem Suchen fand ich dieses
Sudo npm -g install simple-http-server # to install
nserver # to use
Und dann wird es bei http://localhost:8000
dienen.
Leute,
Ich bin auf ein ähnliches Problem gestoßen. Aber mit Fiddler konnte ich das Problem lösen. Das Problem besteht darin, dass die Client-URL, die in der CORS-Implementierung auf der Web-API-Seite konfiguriert ist, keinen nachgestellten Schrägstrich enthalten darf. Nachdem Sie Ihre Anfrage über Google Chrome gesendet und die Registerkarte TextView im Abschnitt Headers von Fiddler überprüft haben, wird in der Fehlermeldung Folgendes angezeigt:
* "Der angegebene Richtlinienursprung your_client_url:/'ist ungültig. Er darf nicht mit einem Schrägstrich enden."
Das ist wirklich eigenartig, weil es im Internet Explorer ohne Probleme funktioniert hat, aber mir beim Testen mit Google Chrome Kopfzerbrechen bereitet hat.
Ich habe den Schrägstrich im CORS-Code entfernt und die Web-API neu kompiliert. Jetzt kann über Chrome und Internet Explorer problemlos auf die API zugegriffen werden. Bitte versuchen Sie es.
Danke, Andy