Aucun en-tête «Access-Control-Allow-Origin» n'est présent sur la ressource demandée. L’origine «…» n’est donc pas autorisée à accéder

135

J'utilise .htaccess pour réécrire les URL et j'ai utilisé la balise de base html pour que cela fonctionne.

Maintenant, lorsque j'essaye de faire une demande ajax, j'obtiens l'erreur suivante:

XMLHttpRequest ne peut pas se charger http://www.example.com/login.php. Aucun en-tête «Access-Control-Allow-Origin» n'est présent sur la ressource demandée. Origin ' http://example.com' n'est donc pas autorisé à accéder.

Th3lmuu90
la source
1
Nevermind ... ça marche maintenant, je ne sais même pas quelle était l'erreur: S
Th3lmuu90
8
Bien que subtile, http://wordicious.comest un domaine différent de celui http://www.wordicious.com/, d'où l'erreur. Btw, s'il fonctionne maintenant et est revenu tout seul, vous devriez probablement supprimer la question.
acdcjunior
@acdcjunior Cela semble être l'erreur, ce qui est une observation judicieuse de votre part. Si vous postez cela comme réponse, je voterais pour.
Waleed Khan
5
C'est une bonne chose que la question n'ait pas été supprimée, sinon je ne l'aurais pas vue aujourd'hui!
icedwater

Réponses:

170

Utiliser au addHeaderlieu d'utiliser la setHeaderméthode,

response.addHeader("Access-Control-Allow-Origin", "*");

*dans la ligne ci-dessus permettra access to all domains.


Pour permettre access to specific domain only:

response.addHeader("Access-Control-Allow-Origin", "http://www.example.com");

Vérifiez ceci blog post.

Jay Patel
la source
4
il montre addheader non défini. Pouvez-vous l'expliquer?
Vaisakh Pc
9
Où dois-je mettre ces lignes?
DaveWalley
14
Où cela devrait-il être ajouté?
Alex
1
Ce billet de blog parle de Node.js et express. Pas de javascript côté client. quelqu'un peut-il confirmer si cela fonctionne?
Sam Eaton
1
Je ne pense pas que cette configuration puisse être faite uniquement du côté client .. Pour savoir où la mettre, ce serait sur le code côté serveur (probablement lors de la construction d'une réponse à une requête)
Chirag Ravindra
145

Pourquoi l'erreur est générée:

Le code JavaScript est limité par la politique de même origine , ce qui signifie qu'à partir d'une page à l'adresse www.example.com, vous ne pouvez faire des requêtes (AJAX) qu'aux services situés à exactement dans le même domaine, dans ce cas, exactement www.example.com( pas example.com - sans le www- ouwhatever.example.com ).

Dans votre cas, votre code Ajax tente d'accéder à un service à http://wordicious.compartir d'une page située sur http://www.wordicious.com.

Bien que très similaires, ils ne sont pas du même domaine. Et lorsqu'ils ne sont pas sur le même domaine, la requête ne réussira que si la réponse de la cible contient un en- Access-Control-Allow-Origintête.

Comme votre page / service à http://wordicious.comn'a jamais été configuré pour présenter un tel en-tête, ce message d'erreur est affiché.

Solution:

Comme dit, les domaines d'origine (où se trouve la page avec JavaScript) et cible (où le JavaScript tente d'atteindre) doivent être les exactement les mêmes.

Votre cas ressemble à une faute de frappe. Ressemble http://wordicious.comet http://www.wordicious.comest en fait le même serveur / domaine. Donc, pour corriger, tapez la cible et l'origine de la même manière: faites-vous des pages / services de demande de code Ajax pour http://www.wordicious.comne pas le fairehttp://wordicious.com . (Peut-être placer l'URL cible de manière relative, comme '/login.php', sans le domaine).



Sur une note plus générale:

Si le problème n'est pas une faute de frappe comme celle de cette question semble être, la solution serait d' ajouter le Access-Control-Allow-Originau domaine cible . L'ajouter dépend, bien entendu, du serveur / de la langue derrière cette adresse. Parfois, une variable de configuration dans l'outil fera l'affaire. D'autres fois, vous devrez ajouter vous-même les en-têtes via le code.

acdcjunior
la source
62

Pour .NET, le serveur peut le configurer dans web.config comme indiqué ci-dessous

 <system.webServer>
   <httpProtocol>
     <customHeaders>
       <add name="Access-Control-Allow-Origin" value="your_clientside_websiteurl" />
     </customHeaders>
   </httpProtocol>
 </system.webServer>

Par exemple, si le domaine du serveur est http://live.makemypublication.com et que le client est http://www.makemypublication.com, configurez-le dans le web.config du serveur comme ci-dessous

 <system.webServer>
   <httpProtocol>
     <customHeaders>
       <add name="Access-Control-Allow-Origin" value="http://www.makemypublication.com" />
     </customHeaders>
  </httpProtocol>
 </system.webServer>
Naga
la source
Une solution encore meilleure. Merci
ANJYR - KODEXPRESSION
Merci beaucoup. Tu as sauvé ma journée entière.
Prateek Gupta
Travailler même après 2 ans: p
Ubiquitous Developers
1
@SyedAliTaqi la question est php, c'est pourquoi la réponse est sous-estimée. mais cela a fonctionné pour moi aussi :)
Ahmad
22

Si vous recevez ce message d'erreur du navigateur:

Aucun en-tête «Access-Control-Allow-Origin» n'est présent sur la ressource demandée. L’origine «…» n’est donc pas autorisée à accéder

lorsque vous essayez de faire une requête Ajax POST / GET à un serveur distant qui est hors de votre contrôle, veuillez oublier cette solution simple:

<?php header('Access-Control-Allow-Origin: *'); ?>

Ce que vous devez vraiment faire, surtout si vous n'utilisez que JavaScript pour faire la requête Ajax, c'est un proxy interne qui prend votre requête et l'envoie au serveur distant.

Tout d'abord dans votre JavaScript, faites un appel Ajax à votre propre serveur, quelque chose comme:

$.ajax({
    url: yourserver.com/controller/proxy.php,
    async:false,
    type: "POST",
    dataType: "json",
    data: data,
    success: function (result) {
        JSON.parse(result);
    },
    error: function (xhr, ajaxOptions, thrownError) {
        console.log(xhr);
    }
});

Ensuite, créez un simple fichier PHP appelé proxy.php pour envelopper vos données POST et les ajouter au serveur URL distant en tant que paramètres. Je vous donne un exemple de la façon dont je contourne ce problème avec l'API de recherche d'hôtels Expedia:

if (isset($_POST)) {
  $apiKey = $_POST['apiKey'];
  $cid = $_POST['cid'];
  $minorRev = 99;

  $url = 'http://api.ean.com/ean-services/rs/hotel/v3/list?' . 'cid='. $cid . '&' . 'minorRev=' . $minorRev . '&' . 'apiKey=' . $apiKey;

  echo json_encode(file_get_contents($url));
 }

En faisant:

 echo json_encode(file_get_contents($url));

Vous faites simplement la même requête mais du côté serveur et après cela, cela devrait fonctionner correctement.

Nizar B.
la source
@NizarBsb vous êtes fou vous le savez !!!!! : D, merci beaucoup votre réponse m'a sauvé la vie
Flash
10

Vous devez l'ajouter au début de votre page php "login.php"

<?php header('Access-Control-Allow-Origin: *'); ?>
Shady Sherif
la source
5
Certainement pas sécurisé.
rappel le
7

vous devez mettre les clés / valeurs des en-têtes dans la réponse de la méthode d'options. par exemple, si vous avez une ressource sur http://mondomaine.com/myresource , dans votre code serveur, vous écrivez

//response handler
void handleRequest(Request request, Response response) {
    if(request.method == "OPTIONS") {
       response.setHeader("Access-Control-Allow-Origin","http://clientDomain.com")
       response.setHeader("Access-Control-Allow-Methods", "GET,POST,PUT,DELETE,OPTIONS");
       response.setHeader("Access-Control-Allow-Headers", "Content-Type");
    }



}
i-systech.com
la source
3

Modifiez la réponse de l'en-tête de l'API en ajoutant les paramètres supplémentaires suivants.

Access-Control-Allow-Credentials: true

Contrôle d'accès-Autoriser-Origine: *

Mais ce n'est pas une bonne solution en matière de sécurité

Piusha
la source
3

La solution de contournement consiste à utiliser un proxy inverse s'exécutant sur votre hôte `` source '' et le transmettant à votre serveur cible, tel que Fiddler:

Lien ici: http://docs.telerik.com/fiddler/configure-fiddler/tasks/usefiddlerasreverseproxy

Ou un proxy Apache Reverse ...

hzrari
la source
cela peut-il être fait au niveau de configuration Apache ou Nginx pour un domaine. Par exemple, si un utilisateur accède à mysite.com (pas de www) et que le XHR demande www.monsite.com, une directive htaccess ou httpd.conf peut-elle résoudre ce problème?
codecowboy
Bien sûr, votre application frontale doit se comporter comme un proxy inverse. par exemple pour Apache, vous devez installer mod_proxy et configurer vos règles en utilisant ProxyPassReverse ( httpd.apache.org/docs/current/mod/… ). Les mêmes fonctionnalités semblent également être disponibles sur Nginx: wiki.nginx.org/LikeApache
hzrari
2

Ajoutez ceci à votre fichier PHP ou à votre contrôleur principal

header("Access-Control-Allow-Origin: http://localhost:9000");
Sam
la source
pour finir - vous avez également besoinheader("Access-Control-Allow-Credentials: true");
Adam
1

Résolu avec l'entrée ci-dessous dans httpd.conf

#CORS Issue
Header set X-Content-Type-Options "nosniff"
Header always set Access-Control-Max-Age 1728000
Header always set Access-Control-Allow-Origin: "*"
Header always set Access-Control-Allow-Methods: "GET,POST,OPTIONS,DELETE,PUT,PATCH"
Header always set Access-Control-Allow-Headers: "DNT,X-CustomHeader,Keep-Alive,Content-Type,Origin,Authentication,Authorization,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control"
Header always set Access-Control-Allow-Credentials true

#CORS REWRITE
RewriteEngine On                  
RewriteCond %{REQUEST_METHOD} OPTIONS 
#RewriteRule ^(.*)$ $1 [R=200,L]
RewriteRule ^(.*)$ $1 [R=200,L,E=HTTP_ORIGIN:%{HTTP:ORIGIN}]]
Sandeep540
la source
La seule façon qui a fonctionné pour moi sur Apache2, CentOS7, Larravel 5 et React
Shakiba Moshiri