web-dev-qa-db-fra.com

Erreur de base AJAX obtient "Aucun en-tête 'Access-Control-Allow-Origin' n'est présent sur la ressource demandée")

J'essaie d'envoyer une demande simplement GET à un certain lien dans une demande jQuery AJAX.

C'est très simple:

$.ajax({
    type: 'GET',
    url: /* <the link as string> */,
    dataType: 'text/html',
    success: function() { alert("Success"); },
    error: function() { alert("Error"); },
});

Cependant, quoi que j'aie essayé, j'ai eu XMLHttpRequest cannot load <page>. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:7776' is therefore not allowed access.

J'ai tout essayé, de l'ajout de header : {} définitions à la demande AJAX pour définir dataType sur JSONP, ou même text/plain, en utilisant simple AJAX au lieu de jQuery, même en téléchargeant un plugin qui active CORS - mais rien ne pourrait aider.

Et la même chose se produit si j'essaie d'accéder à d'autres sites.

Des idées pour une solution correcte et simple? Y en a-t-il du tout?

12
Zoltán Schmidt

C'est par conception. Vous ne pouvez pas faire de requête HTTP arbitraire à un autre serveur à l'aide de XMLHttpRequest à moins que ce serveur ne le permette en mettant un en-tête Access-Control-Allow-Origin pour l'hôte demandeur.

https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS

Vous pouvez le récupérer dans une balise de script (il n'y a pas la même restriction sur les scripts et les images et les feuilles de style), mais à moins que le contenu renvoyé soit un script, cela ne vous fera pas grand-chose.

Voici un tutoriel sur CORS:

http://www.bennadel.com/blog/2327-cross-Origin-resource-sharing-cors-ajax-requests-between-jquery-and-node-js.htm

Tout cela est fait pour protéger l'utilisateur final. En supposant qu'une image est en fait une image, une feuille de style n'est qu'une feuille de style et un script n'est qu'un script, demander ces ressources à un autre serveur ne peut pas vraiment faire de mal.

Mais en général, les demandes multi-origines peuvent faire de très mauvaises choses. Dites que vous, Zoltan, utilisez coolsharks.com. Dites également que vous êtes connecté à mybank.com et qu'il y a un cookie pour mybank.com dans votre navigateur. Supposons maintenant que coolsharks.com envoie une demande AJAX à mybank.com, demandant de transférer tout votre argent dans un autre compte. Parce que vous avez un cookie mybank.com stocké, ils ont réussi à répondre à la demande . Et tout cela se produit à votre insu, car aucun rechargement de page n'a eu lieu. C'est le danger d'autoriser les requêtes intersites générales AJAX.

Si vous souhaitez effectuer des requêtes intersites, vous avez deux options:

  1. Obtenez le serveur auquel vous faites la demande soit
    une. Vous admettre en mettant un en-tête Access-Control-Allow-Origin qui vous inclut (ou *)
    b. Vous fournir une API JSONP.

ou

  1. Écrivez votre propre navigateur qui ne respecte pas les normes et n'a aucune restriction.

Dans (1), vous devez avoir la coopération du serveur auquel vous faites des demandes, et dans (2), vous devez avoir le contrôle sur le navigateur de l'utilisateur final. Si vous ne pouvez pas remplir (1) ou (2), vous n'avez pas de chance.

Cependant, il existe une troisième option (soulignée par charlietfl). Vous pouvez effectuer la demande à partir d'un serveur que vous contrôlez, puis transmettre le résultat à votre page. Par exemple.

<script>
$.ajax({
    type: 'GET',
    url: '/proxyAjax.php?url=http%3A%2F%2Fstackoverflow.com%2F10m',
    dataType: 'text/html',
    success: function() { alert("Success"); },
    error: function() { alert("Error"); }
});
</script>

Et puis sur votre serveur, au plus simple:

<?php
// proxyAjax.php
// ... validation of params
// and checking of url against whitelist would happen here ...
// assume that $url now contains "http://stackoverflow.com/10m"
echo file_get_contents($url);

Bien sûr, cette méthode peut rencontrer d'autres problèmes:

  • Le site pour lequel vous êtes un proxy requiert-il le référent correct ou une certaine adresse IP?
  • Les cookies doivent-ils être transmis au serveur cible?
  • Votre liste blanche vous protège-t-elle suffisamment contre toute demande arbitraire?
  • Quels en-têtes (par exemple, modifier l'heure, etc.) allez-vous renvoyer au navigateur lorsque votre serveur les a reçus et lesquels allez-vous omettre ou modifier?
  • Votre serveur sera-t-il impliqué comme ayant fait une demande qui était illégale (puisque vous agissez en tant que proxy)?

Je suis sûr qu'il y en a d'autres. Mais si aucun de ces problèmes ne l'empêche, cette troisième méthode pourrait très bien fonctionner.

7
Chris Middleton

vous pouvez demander aux développeurs de ce domaine s'ils définiraient l'en-tête approprié pour vous, cette restriction est uniquement pour javascript, en gros vous pouvez demander la ressource à votre serveur avec php ou autre et le javascript demande les données de votre domaine puis

3
john Smith