L'origine <origin> n'est pas autorisée par Access-Control-Allow-Origin

184
XMLHttpRequest cannot load http://localhost:8080/api/test. Origin http://localhost:3000 is not allowed by Access-Control-Allow-Origin. 

J'ai lu sur les demandes ajax interdomaines et je comprends le problème de sécurité sous-jacent. Dans mon cas, 2 serveurs fonctionnent localement et aiment activer les requêtes interdomaines pendant les tests.

localhost:8080 - Google Appengine dev server
localhost:3000 - Node.js server

J'émets une requête ajax à localhost:8080 - GAE serverpendant que ma page est chargée à partir du serveur de nœuds. Quel est le plus simple et le plus sûr (je ne veux pas démarrer Chrome avec l' disable-web-securityoption). Si je dois changer 'Content-Type', dois-je le faire sur le serveur de nœuds? Comment?

bsr
la source
Une solution plus rapide peut être trouvée ici: stackoverflow.com/a/21622564/4455570
Gabriel Wamunyu

Réponses:

195

Puisqu'ils fonctionnent sur des ports différents, ils sont différents en JavaScript origin. Peu importe qu'ils soient sur la même machine / nom d'hôte.

Vous devez activer CORS sur le serveur (localhost: 8080). Consultez ce site: http://enable-cors.org/

Tout ce que vous avez à faire est d'ajouter un en-tête HTTP au serveur:

Access-Control-Allow-Origin: http://localhost:3000

Ou, pour plus de simplicité:

Access-Control-Allow-Origin: *

Je pense que n'utilisez pas "*" si votre serveur tente de définir un cookie et que vous utilisez withCredentials = true

lorsqu'il répond à une demande d'informations d'identification, le serveur doit spécifier un domaine et ne peut pas utiliser de caractères génériques.

Vous pouvez en savoir plus withCredentialsici

Fusée Hazmat
la source
si nous voulons ajouter cet en-tête dans un HTML, que devons-nous faire pour cela?
Azam Alvi
1
Je ne pensais pas que ce port était nécessaire, mais si vous utilisez un port non standard tel que 3000, vous devez l'inclure dans la politique CORS.
Michael Connor
4
Merci pour cette réponse. Je veux juste souligner les implications de sécurité de l'utilisation de «*» comme valeur ici. Cela permet toutes les origines: developer.mozilla.org/en-US/docs/Web/HTTP/Headers/... On dirait que le premier exemple serait le meilleur en termes de moindre accès. Détails sur la façon de procéder avec plusieurs domaines ici: stackoverflow.com/a/1850482/1566623
Christopher Kuttruff
14
Par souci de clarté, quand il est dit que vous devez "ajouter un en-tête HTTP au serveur", cela signifie que l'en- Access-Control-Allow-Origintête donné doit être un en-tête ajouté aux réponses HTTP que le serveur envoie. Cet en-tête doit faire partie de la réponse du serveur, il n'a pas besoin de faire partie de la demande du client . Plus précisément, ce qui se passe avant que le client ne fasse la demande que vous souhaitez, le navigateur envoie une OPTIONSdemande avant lui, et si la réponse du serveur à cette OPTIONSdemande ne contient pas l'en-tête, le navigateur n'enverra pas la demande souhaitée.
AjaxLeung
1
Il est important de lire les conseils pertinents pour vos serveurs backend sur enable-cors.org.
Karlth
69

Si vous avez besoin d'une solution rapide dans Chrome pour les requêtes ajax, ce plugin Chrome vous permet automatiquement d'accéder à n'importe quel site à partir de n'importe quelle source en ajoutant l'en-tête de réponse approprié

Extension Chrome Allow-Control-Allow-Origin: *

Billy Baker
la source
6
Je ne sais pas pourquoi vous n'obtenez pas plus de votes positifs. C'est le moins intrusif pour le développement sur localhost avec Chrome.
David Betz
définitivement d'accord. Facile à activer pour le développement localhost sur un serveur distant sans avoir à modifier la configuration du serveur distant.
Jens Wegar
@DavidBetz: considérant que vous vérifiez l'extension et que vous lui faites confiance, bien sûr;)
haylem
2
CECI DEVRAIT ÊTRE LA RÉPONSE TOP! Surtout quand localhost est concerné.
M. Benedict
16
Si c'était une bonne solution, CORS n'aurait pas été inventé en premier lieu. L'application de cet en-tête à n'importe quel hôte désactive la protection CORS et vous expose à des scripts malveillants, pas seulement les vôtres. Ne soyez pas surpris si votre compte bancaire est soudainement vide.
dolmen
54

Vous devez activer CORS pour résoudre ce problème

si votre application est créée avec simple node.js

définissez-le dans vos en-têtes de réponse comme

var http = require('http');

http.createServer(function (request, response) {
response.writeHead(200, {
    'Content-Type': 'text/plain',
    'Access-Control-Allow-Origin' : '*',
    'Access-Control-Allow-Methods': 'GET,PUT,POST,DELETE'
});
response.end('Hello World\n');
}).listen(3000);

si votre application est créée avec un framework express

utiliser un middleware CORS comme

var allowCrossDomain = function(req, res, next) {
    res.header('Access-Control-Allow-Origin', "*");
    res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
    res.header('Access-Control-Allow-Headers', 'Content-Type');
    next();
}

et postulez via

app.configure(function() {
    app.use(allowCrossDomain);
    //some other code
});    

Voici deux liens de référence

  1. comment autoriser les cors dans express nodejs
  2. plongée-dans-node-js-very-first-app #voir la section Ajax
mithunsatheesh
la source
pouvez-vous s'il vous plaît préciser, comment utiliser config.allowedDomains. dire dans mon cas quel uri dois-je y mettre?
bsr
@bsr: vous pouvez utiliser *ou celui auquel specific domainvous souhaitez donner accès.
mithunsatheesh
1
alors suis-je le seul à obtenir app.configure()une erreur de fonction?
Pramesh Bajracharya
@PrameshBajrachaya Je n'ai pas inclus la partie "app.configure" - uniquement "app.use (allowCrossDomain)", et cela a fonctionné pour moi.
Giorgos Sfikas
8

J'accepte la réponse de @Rocket Hazmat car elle me conduit à la solution. C'était en effet sur le serveur GAE dont j'avais besoin pour définir l'en-tête. Je devais régler ces

"Access-Control-Allow-Origin" -> "*"
"Access-Control-Allow-Headers" -> "Origin, X-Requested-With, Content-Type, Accept"

le réglage n'a "Access-Control-Allow-Origin" donné qu'une erreur

Request header field X-Requested-With is not allowed by Access-Control-Allow-Headers.

De plus, si un jeton d'authentification doit être envoyé, ajoutez-le également

"Access-Control-Allow-Credentials" -> "true"

Aussi, chez le client, définissez withCredentials

cela provoque l'envoi de 2 requêtes au serveur, une avec OPTIONS. Le cookie d'authentification n'est pas envoyé avec lui, il faut donc traiter l'authentification externe.

bsr
la source
7

Dans router.js, ajoutez simplement du code avant d'appeler les méthodes get / post. Cela fonctionne pour moi sans erreurs.

//Importing modules @Brahmmeswar
const express = require('express');
const router = express.Router();

const Contact = require('../models/contacts');

router.use(function(req, res, next) {
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
    next();
  });
Brahmmeswara Rao Palepu
la source
5

J'étais confronté à un problème en appelant la ressource d'origine croisée en utilisant ajax à partir de chrome.

J'ai utilisé le nœud js et le serveur http local pour déployer mon application nœud js.

J'obtenais une réponse d'erreur, lorsque j'accède à la ressource cross origin

J'ai trouvé une solution là-dessus,

1) J'ai ajouté le code ci-dessous à mon fichier app.js

res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "X-Requested-With");

2) Dans ma page html appelée ressource d'origine croisée en utilisant $.getJSON();

$.getJSON("http://localhost:3000/users", function (data) {
    alert("*******Success*********");
    var response=JSON.stringify(data);
    alert("success="+response);
    document.getElementById("employeeDetails").value=response;
});
Chaitanya
la source
5

Si vous utilisez express, vous pouvez utiliser le middleware cors comme suit:

var express = require('express')
var cors = require('cors')
var app = express()

app.use(cors())
Akalanka Weerasooriya
la source
3

Ajoutez ceci à votre serveur NodeJS ci-dessous les importations:

app.use(function(req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
  next();
});
Ryan Cocuzzo
la source
3

Si vous obtenez 403 après cela, veuillez réduire les filtres de la configuration tomcat WEB.XML comme suit:

<filter>
  <filter-name>CorsFilter</filter-name>
  <filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
  <init-param>
    <param-name>cors.allowed.origins</param-name>
    <param-value>*</param-value>
  </init-param>
  <init-param>
    <param-name>cors.allowed.methods</param-name>
    <param-value>GET,POST,HEAD,OPTIONS,PUT</param-value>
  </init-param>
  <init-param>
    <param-name>cors.allowed.headers</param-name>
    <param-value>Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers</param-value>
  </init-param>
  <init-param>
    <param-name>cors.exposed.headers</param-name>
    <param-value>Access-Control-Allow-Origin,Access-Control-Allow-Credentials</param-value>
  </init-param>
</filter>
Farbod Aprin
la source
2

J'ai enfin la réponse pour apache Tomcat8

Vous devez éditer le fichier tomcat web.xml.

ce sera probablement dans le dossier webapps,

sudo gedit /opt/tomcat/webapps/your_directory/WEB-INF/web.xml

trouvez-le et modifiez-le

<web-app>


<filter>
  <filter-name>CorsFilter</filter-name>
  <filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
  <init-param>
    <param-name>cors.allowed.origins</param-name>
    <param-value>*</param-value>
  </init-param>
  <init-param>
    <param-name>cors.allowed.methods</param-name>
    <param-value>GET,POST,HEAD,OPTIONS,PUT</param-value>
  </init-param>
  <init-param>
    <param-name>cors.allowed.headers</param-name>
    <param-value>Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers</param-value>
  </init-param>
  <init-param>
    <param-name>cors.exposed.headers</param-name>
    <param-value>Access-Control-Allow-Origin,Access-Control-Allow-Credentials</param-value>
  </init-param>
  <init-param>
    <param-name>cors.support.credentials</param-name>
    <param-value>true</param-value>
  </init-param>
  <init-param>
    <param-name>cors.preflight.maxage</param-name>
    <param-value>10</param-value>
  </init-param>
</filter>


<filter-mapping>
  <filter-name>CorsFilter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>



</web-app>

Cela permettra à tous les hôtes Access-Control-Allow-Origin. Si vous avez besoin de le changer de tous les hôtes à votre hôte uniquement, vous pouvez modifier le

<param-name>cors.allowed.origins</param-name>
<param-value>http://localhost:3000</param-value>

ci-dessus de * à votre http: // your_public_IP ou http://www.example.com

vous pouvez vous référer ici à la documentation du filtre Tomcat

Merci

Shinto Joseph
la source
1

Salut C'est le moyen de résoudre le problème CORS dans le nœud Ajoutez simplement ces lignes du côté serveur "api" dans Node.js (ou quel que soit votre fichier serveur), avant cela assurez-vous d'installer "cors"

    const express = require('express');
    const app = express();
    app.use(express.json());
    var cors = require('cors');
    app.use(cors());
Saad Abbasi
la source
0

utilisez dataType: 'jsonp', ça marche pour moi.

   async function get_ajax_data(){

       var _reprojected_lat_lng = await $.ajax({

                                type: 'GET',

                                dataType: 'jsonp',

                                data: {},

                                url: _reprojection_url,

                                error: function (jqXHR, textStatus, errorThrown) {

                                    console.log(jqXHR)

                                },

                                success: function (data) {

                                    console.log(data);



                                    // note: data is already json type, you just specify dataType: jsonp

                                    return data;

                                }

                            });





 } // function               
hoogw
la source
0

Pour PHP, utilisez ceci pour définir les en-têtes.

header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Methods: PUT, GET, POST");
header("Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept");
Hamza Waleed
la source
0
router.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Methods", "*");
res.header("Access-Control-Allow-Headers", "*");
next();});

ajoutez ceci à vos itinéraires que vous appelez depuis le front-end. Ex - si vous appelez http: // localhost: 3000 / users / register, vous devez ajouter ce fragment de code sur votre fichier .js back-end que cette route établit.

Sujeewa K. Abeysinghe
la source
0

Au cas où quelqu'un chercherait la solution, si vous utilisez express, voici la solution rapide.

const express = require('express')
const cors = require('cors')
const app = express()

1) installer des cors en utilisant npm npm install cors --save

2) l'importer [exiger] const cors = require('cors')

3) utilisez-le comme middleware app.use(cors())

pour plus de détails et l'utilisation des cors . Voilà, j'espère que cela fonctionne.

Badri Paudel
la source