Erreur XmlHttpRequest: Origin null n'est pas autorisé par Access-Control-Allow-Origin
Je développe une page qui tire des images de Flickr et Panoramio via le support AJAX de jQuery.
Le côté Flickr fonctionne bien, mais quand j'essaie de {[2] } de Panoramio, je vois une erreur dans la console de Chrome:
XMLHttpRequest ne peut pas charger 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 n'est pas autorisé par Access-Control-Allow-Origin.
Si j'interroge directement cette URL à partir d'un navigateur, cela fonctionne bien. Que se passe-t-il, et puis-je contourner cela? Est-ce que je compose mal ma requête, ou est-ce quelque chose que Panoramio fait pour entraver ce que j'essaie de faire?
Google n'a pas trouvé de correspondance utile sur le message d'erreur .
Modifier
Voici un exemple de code qui montre le problème:
$().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);
});
});
Vous pouvez exécutez l'exemple en ligne.
Modifier 2
Merci à Darin pour son aide. LE CODE CI-DESSUS EST FAUX. utilisez ceci à la place:$().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...
});
});
16 réponses
Pour mémoire, pour autant que je sache, vous avez eu deux problèmes:
Vous ne passiez pas un spécificateur de type "jsonp" à votre
$.get
, donc il utilisait un XMLHttpRequest ordinaire. Cependant, votre navigateur a pris en charge CORS (Cross-Origin Resource Sharing) pour autoriser XMLHttpRequest cross-domain si le serveur L'a activé. C'est là que l'en-têteAccess-Control-Allow-Origin
est entré.Je crois que vous avez mentionné que vous l'exécutiez à partir d'un fichier: / / URL. Il y a deux façons pour les en-têtes CORS de signal qu'un XHR Cross-domain est OK. L'un consiste à envoyer
Access-Control-Allow-Origin: *
(ce qui, si vous atteignez Flickr via$.get
, doit avoir été fait) tandis que l'autre devait renvoyer le contenu de l'en-têteOrigin
. Cependant, les URLfile://
produisent unOrigin
null qui ne peut pas être autorisé via echo-back.
Le premier a été résolu de manière détournée par la suggestion de Darin d'utiliser $.getJSON
. Il fait un peu de magie pour changer le type de requête de sa valeur par défaut de "json" à "jsonp" s'il voit la sous-chaîne callback=?
dans L'URL.
Qui a résolu le second en n'essayant plus d'effectuer une requête CORS à partir d'une URL file://
.
Pour clarifier pour d'autres personnes, voici les instructions de dépannage simples:
- Si vous essayez D'utiliser JSONP, assurez-vous que l'un des éléments suivants est le cas:
- vous utilisez
$.get
et définissezdataType
àjsonp
. - vous utilisez
$.getJSON
et incluezcallback=?
dans L'URL.
- vous utilisez
- Si vous essayez de faire un inter-domaine via XMLHttpRequest de la SCRO...
- assurez-vous que vous testez via
http://
. Les Scripts exécutés viafile://
ont un support limité pour CORS. - assurez-vous que le navigateur supporte réellement CORS. (Opera et Internet Explorer sont en retard à la fête)
- assurez-vous que vous testez via
Vous devez peut-être ajouter un en-tête dans votre script appelé, voici ce que j'ai dû faire en PHP:
header('Access-Control-Allow-Origin: *');
Plus de détails dans Bienvenue sur
Pour un projet HTML simple:
cd project
python -m SimpleHTTPServer 8000
Ensuite, parcourez votre fichier.
Fonctionne pour moi sur Google Chrome v5. 0. 375. 127 (je reçois l'alerte):
$.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);
});
Aussi, je vous recommande d'utiliser le $.getJSON()
méthode à la place comme la précédente ne fonctionne pas sur IE8 (au moins sur ma machine):
$.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);
});
, Vous pouvez essayer de en ligne à partir d'ici.
Mise à jour:
Maintenant que vous avez montré votre code, je peux voir le problème avec lui. Vous avez à la fois une fonction anonyme et une fonction en ligne, mais les deux seront appelées processImages
. C'est comme ça que jQuery est Le support JSONP fonctionne. Remarquez comment je définis le callback=?
afin que vous puissiez utiliser une fonction anonyme. Vous pouvez lire plus à ce sujet dans la documentation.
Une autre remarque est que vous ne devriez pas appeler eval. Le paramètre passé à votre fonction anonyme sera déjà analysé dans JSON par jQuery.
Tant que le serveur demandé prend en charge le format de données JSON, utilisez L'interface JSONP (JSON Padding). Il vous permet de faire des demandes de domaine externes sans serveurs proxy ou des trucs d'en-tête de fantaisie.
C'est la même politique d'origine, vous devez utiliser une interface JSON-P ou un proxy fonctionnant sur le même hôte.
Nous l'avons géré via le fichier http.conf
(édité puis redémarré le service HTTP):
<Directory "/home/the directory_where_your_serverside_pages_is">
Header set Access-Control-Allow-Origin "*"
AllowOverride all
Order allow,deny
Allow from all
</Directory>
Dans le Header set Access-Control-Allow-Origin "*"
, vous pouvez mettre une URL précise.
Si vous effectuez des tests locaux ou appelez le fichier à partir de quelque chose comme file://
, Vous devez désactiver la sécurité du navigateur.
Sur MAC:
open -a Google\ Chrome --args --disable-web-security
Dans mon cas, le même code a bien fonctionné sur Firefox, mais pas sur Google Chrome. La console JavaScript de Google Chrome a déclaré:
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"
J'ai dû laisser tomber la partie www De L'URL Ajax pour qu'elle corresponde correctement à l'URL d'origine et cela a bien fonctionné alors.
Tous les serveurs ne prennent pas en charge jsonp. Il nécessite que le serveur définisse la fonction de rappel dans ses résultats. Je l'utilise pour obtenir des réponses json à partir de sites qui renvoient JSON pur mais ne supportent pas jsonp:
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;
});
}
J'utilise le serveur Apache, j'ai donc utilisé le module mod_proxy. Activer les modules:
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so
Puis Ajouter:
ProxyPass /your-proxy-url/ http://service-url:serviceport/
Enfin, passez proxy-url à votre script.
Comme note finale la documentation Mozilla dit explicitement que
L'exemple ci-dessus échouerait si l'en-tête était: Access-Control-Allow-Origin:*. puisque le Access-Control-Allow-Origin mentionne explicitement http://foo.exemple, le contenu de credential-cognizant est renvoyé au web appelant contenu.
En conséquence n'est pas simplement une mauvaise pratique à utiliser '*'. Ne fonctionne tout simplement pas :)
J'ai aussi eu la même erreur dans Chrome (Je n'ai pas testé d'autres navigateurs). C'était dû au fait que je naviguais sur domain.com au lieu de www.domain.com. un peu étrange, mais je pourrais résoudre le problème en ajoutant les lignes suivantes à .htaccess. Il redirige domain.com pour www.domain.com et le problème a été résolu. Je suis un visiteur web paresseux donc je ne tape presque jamais le www mais apparemment dans certains cas, il est nécessaire.
RewriteEngine on
RewriteCond %{HTTP_HOST} ^domain\.com$ [NC]
RewriteRule ^(.*)$ http://www.domain.com/$1 [R=301,L]
Assurez-vous que vous utilisez la dernière version de JQuery. Nous étions confrontés à cette erreur pour jQuery 1.10.2 et l'erreur a été résolue après avoir utilisé jQuery 1.11.1
Les Gens,
J'ai rencontré un problème similaire. Mais en utilisant Fiddler, j'ai pu résoudre le problème. Le problème est que l'URL client configurée dans L'implémentation CORS du côté de L'API Web ne doit pas avoir de barre oblique finale. Après avoir soumis votre demande via Google Chrome et inspecté l'onglet TextView de la section Headers de Fiddler, le message d'erreur indique quelque chose comme ceci:
* "l'origine spécifiée de la stratégie your_client_url:/' n'est pas valide. il ne peut pas se terminer par une barre oblique."
C'est vraiment bizarre parce que cela a fonctionné sans aucun problème sur Internet Explorer, mais m'a donné un mal de tête lors des tests en utilisant Google Chrome.
J'ai supprimé la barre oblique dans le code CORS et recompilé L'API Web, et maintenant l'API est accessible via Chrome et Internet Explorer sans aucun problème. Veuillez donner un coup de cette.
Merci, Andy
Il y a un petit problème dans la solution postée par CodeGroover ci-dessus , où si vous modifiez un fichier, vous devrez redémarrer le serveur pour utiliser réellement le fichier mis à jour (au moins, dans mon cas).
Donc en cherchant un peu, j'ai trouvé celui-ci à utiliser:
sudo npm -g install simple-http-server # to install
nserver # to use
Et puis il servira à http://localhost:8000
.