web-dev-qa-db-fra.com

Autoriser CORS REST demande à une application Express/Node.js sur Heroku

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

La première demande, faite automatiquement par le frontal javascript, est adressée à/api/search? Uri = et semble échouer lors de la requête "preflight" OPTIONS. 

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 }));
});

Sur la console Chrome, je récupère les en-têtes suivants:

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 de statut: 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 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.

80
Jamie

J'ai vérifié votre code sur une application propre ExpressJS et cela fonctionne très bien.

Essayez de déplacer votre app.use(allowCrossDomain) en haut de la fonction de configuration.

55
Olegas

pour prendre en charge les cookies avec des informations d'identification, vous avez besoin de cette ligne xhr.withCredentials = true;

mdn docs xhr.withCredentials

Dans Express Server, 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();
});`
3
doron aviguy

Ce ne pouvait pas être le cas pour la plupart des gens parcourant cette question, mais j'avais 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'a pas été défini dans les variables d'environnement, de sorte que le jeton n'a pas pu être signé ..__ Ceci a provoqué toute requête POST qui repose sur la vérification ou la signature d'un jeton obtenez un délai et retournez une erreur 503, en indiquant au navigateur qu'il y a quelque chose qui ne va pas dans CORS, ce qui n'est pas .. .. L'ajout de la variable d'environnement dans Heroku a résolu le problème.

J'espère que ça aidera quelqu'un.

0
CatBrownie

J'ajoute ceci en tant que réponse uniquement parce que le message original a été mis en commentaire et que, de ce fait, le vôtre l'a vraiment oublié. parcouru cette page.

Comme @ConnorLeech le souligne 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ée de la réponse de M. Leech) et peut également être appliquée de manière plus stricte et plus configurable, comme indiqué dans leur docs .

Il convient également de noter que le commentaire original mentionné ci-dessus a été fait en 2014. Nous sommes en 2019 et nous regardons la page la page github du paquet npm le rapport a été mis à jour il y a neuf jours à peine.

0
flyingace