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...
  });
});
511
demandé sur Kevin Christopher Henry 2010-08-29 20:12:40

16 réponses

Pour mémoire, pour autant que je sache, vous avez eu deux problèmes:

  1. 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ête Access-Control-Allow-Origin est entré.

  2. 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ête Origin. Cependant, les URL file:// produisent un Origin 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:

  1. Si vous essayez D'utiliser JSONP, assurez-vous que l'un des éléments suivants est le cas:
    • vous utilisez $.get et définissez dataType à jsonp.
    • vous utilisez $.getJSON et incluez callback=? dans L'URL.
  2. Si vous essayez de faire un inter-domaine via XMLHttpRequest de la SCRO...
    1. assurez-vous que vous testez via http://. Les Scripts exécutés via file:// ont un support limité pour CORS.
    2. assurez-vous que le navigateur supporte réellement CORS. (Opera et Internet Explorer sont en retard à la fête)
411
répondu ssokolow 2012-04-08 16:00:16

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 (en français).

74
répondu Thomas Decaux 2011-05-23 14:17:59

Pour un projet HTML simple:

cd project
python -m SimpleHTTPServer 8000

Ensuite, parcourez votre fichier.

67
répondu CodeGroover 2012-06-11 15:54:56

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.

20
répondu Darin Dimitrov 2010-08-29 16:55:38

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.

8
répondu Cheng Chen 2017-03-16 09:05:21

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.

5
répondu Quentin 2010-08-29 16:15:25

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.

5
répondu romu31 2012-06-11 15:53:46

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

4
répondu user2701060 2013-08-20 19:15:28

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.

3
répondu Kalpesh Patel 2012-06-11 15:54:33

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;
    });
}
2
répondu mAsT3RpEE 2017-03-16 09:10:21

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.

1
répondu zenio 2012-04-02 11:52:05

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

1
répondu user2688838 2013-08-16 09:11:13

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]
0
répondu mslembro 2013-09-30 07:47:51

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

0
répondu Ganesh Kamath - 'Code Frenzy' 2014-07-10 06:32:30

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

0
répondu andymenon 2014-08-21 05:18:05

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.

0
répondu MiJyn 2018-05-05 23:24:49