XHR cross domain avec Node.js

Les requêtes ajax entre domaines, ou XHR cross domain pour les intimes, permettent d’envoyer des requêtes JavaScript depuis une url A vers une url B. C’est par exemple ce que fait le script de Google Analytics. Il envoie des requêtes d’une url A (votre site) vers une url B (les serveurs de Google). De manière générale, cela sert par exemple pour faire des requêtes d’api. Pour d’évidentes raisons de sécurité, le CORS n’est pas activé par défaut. Voyons comment le paramétrer pour NodeJs.

Pour ma part, c’est en développant mon application de contacts que j’ai été confronté à cette problématique. L’application est construite autour d’une API en Node.js (et Express.js mais les exemples peuvent aisément être adapté en Node pur) et la partie client repose sur Backbone.js. J’ai donc porté la partie client sur Cordova pour obtenir des applications natives iOS/Andoid.

De cette manière, la partie client n’est plus téléchargée depuis le serveur de l’application, mais elle réside sur l’appareil, en local. J’ai dans un premier temps autorisé le CORS. Il suffit pour cela d’ajouter des headers dans la configuration du serveur (server.js ou app.js en général) :

// on précise ici qu'on autorise toutes les sources
// puis dans le second header, quels headers http sont acceptés
app.use(function(request, response, next) {
  response.header("Access-Control-Allow-Origin", "*");
  response.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
  next();
});

Jusque là tout fonctionnait bien pour mes requêtes GET. Cependant, lorsque j’ai voulu modifier des données avec un PUT, mon navigateur envoyait une entête http OPTIONS. J’ai fait quelques recherches et je découvre que cet en-tête HTTP 1.1 OPTIONS s’appelle une entête preflight. Elle précède la requête POST, DELETE ou PUT et demande au serveur ce qu’il accepte.

Si on veut que le navigateur envoie la requête suivante, il faut donc que le serveur lui réponde de manière adéquate. Pour ma part voici ce que j’ai mis en place :

// dès qu'une requête de type options est envoyé à une url de l'api
// le serveur répond qu'il accepte les méthodes GET, PUT, POST, DELETE et OPTIONS
app.options('/api/*', function (request, response, next) {
    response.header("Access-Control-Allow-Methods", "GET, PUT, POST, DELETE, OPTIONS");
    response.send();
});

Vous noterez qu’il est possible de définir des politiques différentes selon les url. Enfin, sachez qu’il existe un package NPM pour configurer le CORS.

Dernier point, pour ceux qui veulent implémenter le CORS plus finement côté frontend, il y a un intéressant article à ce sujet sur HTML5rocks.

Il n'y a pas encore de commentaire

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *