101 votes

Autoriser les requêtes REST CORS vers une application Express/Node.js sur Heroku

J'ai écrit une API REST sur le framework express pour node.js qui fonctionne pour les requêtes provenant de la console js dans Chrome, de la barre d'URL, etc. J'essaie maintenant de la faire fonctionner pour les demandes provenant d'une autre application, sur un domaine différent (CORS).

La première demande, effectuée automatiquement par le frontal javascript, est destinée à /api/search?uri=, et semble échouer sur la demande OPTIONS "preflight".

Dans mon application express, j'ajoute des en-têtes CORS, en utilisant :

var allowCrossDomain = function(req, res, next) {
    res.header('Access-Control-Allow-Origin', '*');
    res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
    res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization, Content-Length, X-Requested-With');

    // intercept OPTIONS method
    if ('OPTIONS' == req.method) {
      res.send(200);
    }
    else {
      next();
    }
};

et :

app.configure(function () {
  app.use(express.bodyParser());
  app.use(express.methodOverride());
  app.use(app.router);
  app.use(allowCrossDomain);
  app.use(express.static(path.join(application_root, "public")));
  app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
});

Depuis la console Chrome, j'obtiens ces en-têtes :

URL de la demande : http://furious-night-5419.herokuapp.com/api/search?uri=http%3A%2F%2Flocalhost%3A5000%2Fcollections%2F1%2Fdocuments%2F1

Méthode de demande : OPTIONS

Code d'état : 200 OK

En-têtes de demande

Accept:*/*
Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.3
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Access-Control-Request-Headers:origin, x-annotator-auth-token, accept
Access-Control-Request-Method:GET
Connection:keep-alive
Host:furious-night-5419.herokuapp.com
Origin:http://localhost:5000
Referer:http://localhost:5000/collections/1/documents/1
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_4) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.56 Safari/536.5

Paramètres de la chaîne de requête

uri:http://localhost:5000/collections/1/documents/1

En-têtes de réponse

Allow:GET
Connection:keep-alive
Content-Length:3
Content-Type:text/html; charset=utf-8
X-Powered-By:Express

Cela ressemble-t-il à un manque d'en-têtes appropriés envoyés par l'application API ?

Merci.

0 votes

J'obtiens cette erreur dans un code que je n'ai pas écrit, mais je ne comprends pas l'utilité d'un gestionnaire pour la fonction OPTIONS méthode. Quelqu'un pourrait-il m'aider à comprendre pourquoi ne pas traiter uniquement la méthode POST au lieu de traiter les deux POST y OPTIONS méthode ?

0 votes

Vous pouvez également inclure PATCH si vous l'utilisez à la place de PUT pour mettre à jour une ressource

66voto

Olegas Points 4787

J'ai testé votre code sur une application ExpressJS propre et il fonctionne parfaitement.

Essayez de déplacer votre app.use(allowCrossDomain) au sommet de la fonction de configuration.

8 votes

La raison en est qu'il doit être défini avant la fonction app.use(app.router); A la vôtre !

0 votes

Dans mon cas, le POST suivant n'est pas appelé après avoir renvoyé res.send(200) lorsque req.method == 'OPTIONS'. Est-ce que j'ai oublié quelque chose d'autre ?

0 votes

2Aldo : Code nécessaire. Peut-être avez-vous oublié certains en-têtes ? Si votre client n'envoie pas de POST après que votre serveur ait correctement servi une requête OPTIONS de contrôle préalable, essayez de vérifier la console des outils de développement. WebKit enregistre ce type d'erreurs dans la console de l'inspecteur Web.

5voto

flyingace Points 1265

Je l'ajoute en tant que respuesta seulement parce que le message original a été placé en tant que commentaire et que, de ce fait, il a été ignoré par votre serviteur la première fois que j'ai consulté cette page.

Comme le souligne @ConnorLeech dans son commentaire à la réponse acceptée ci-dessus, il existe un paquet npm très pratique appelé, sans surprise, cors . Son utilisation est aussi simple que var cors = require('cors'); app.use(cors()); (encore une fois, tiré de la réponse de M. Leech) et peut également être appliqué d'une manière plus stricte et plus configurable, comme indiqué dans le document intitulé docs .

Il peut également être utile de souligner que le commentaire original auquel je fais référence ci-dessus a été fait en 2014. Nous sommes maintenant en 2019 et en regardant les la page github du paquet npm le dépôt a été mis à jour il y a neuf jours.

4voto

doron aviguy Points 258

Pour supporter les cookies avec des certificats, vous avez besoin de cette ligne xhr.withCredentials = true;

mdn docs xhr.withCredentials

Dans le Serveur Express, ajoutez ce bloc avant tous les autres

`app.all('*', function(req, res, next) {
     var origin = req.get('origin'); 
     res.header('Access-Control-Allow-Origin', origin);
     res.header("Access-Control-Allow-Headers", "X-Requested-With");
     res.header('Access-Control-Allow-Headers', 'Content-Type');
     next();
});`

2voto

CatBrownie Points 140

Il se peut que ce ne soit pas le cas pour la plupart des personnes qui parcourent cette question, mais j'ai eu exactement le même problème et la solution n'était pas liée à CORS .

Il s'avère que le secret du jeton web JSON string n'était pas défini dans les variables d'environnement, donc le jeton ne pouvait pas être signé. Cela a causé à tout POST qui s'appuie sur la vérification ou la signature d'un jeton pour obtenir un délai d'attente et renvoyer un message de type 503 qui indique au navigateur qu'il y a un problème dans CORS ce qui n'est pas le cas. L'ajout de la variable d'environnement dans Heroku a résolu le problème.

J'espère que cela aidera quelqu'un.

2voto

Paridhi shah Points 49

enter image description here

Suivez les étapes ci-dessous :

npm install cors --save

Dans votre fichier Root js :

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X