web-dev-qa-db-fra.com

Récupère la requête GET avec des en-têtes personnalisés ReactJS

J'essaie d'envoyer une requête GET à une API, mais lorsque j'ajoute des en-têtes personnalisés dans le code, il se passe quelque chose d'étrange .. Quelque part, la méthode de requête passe à OPTIONS lorsqu'elle atteint le serveur Web.

Mais lorsque je fais la même chose sans en-têtes, ce sera un type GET . Lorsque j'utilise le postman de l'application (outil de développement d'API), la requête fonctionne bien!

code requis:

    let token = this.generateClientToken(privateKey, message);

    let myheaders = {
      "appID": appID,
      "authorizationkey": token
    }

    fetch('http://localhost:8080/api/app/postman', {
      method: "GET",
      // body: JSON.stringify(''),
      headers: myheaders
    }).then(function(response) {
      console.log(response.status);     //=> number 100–599
      console.log(response.statusText); //=> String
      console.log(response.headers);    //=> Headers
      console.log(response.url);        //=> String

      return response.text()
    }, function(error) {
      console.log(error.message); //=> String
    })
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

Sortie du journal du serveur (avec en-têtes):

worker_1  | 172.18.0.4 -  17/Mar/2017:15:47:44 +0000 "OPTIONS /index.php" 403
web_1     | 172.18.0.1 - - [17/Mar/2017:15:47:44 +0000] "OPTIONS /api/app/postman HTTP/1.1" 403 5 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:54.0) Gecko/20100101 Firefox/54.0" "-"

Sortie du journal du serveur (sans en-têtes):

worker_1  | 172.18.0.4 -  17/Mar/2017:16:01:49 +0000 "GET /index.php" 403
web_1     | 172.18.0.1 - - [17/Mar/2017:16:01:49 +0000] "GET /api/app/postman HTTP/1.1" 403 5 "http://localhost:3000/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:54.0) Gecko/20100101 Firefox/54.0" "-"

Ajout des modules NPM pour la prise en charge de l'extraction dans des navigateurs supplémentaires:
https://github.com/github/fetch#obtaining-the-response-url
https://github.com/taylorhakes/promise-polyfill

Qu'est-ce que j'oublie ici? Tout me semble correct.

J'utilise firefox development edition pour tester l'application Reactjs en l'exécutant avec NPM start

7
Steven Bakker

Vous souhaiterez probablement installer le package cors npm https://www.npmjs.com/package/cors sur le serveur sur lequel vous avez votre application de noeud http://localhost:8080/api/app en cours d'exécution.

https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Preflighted_requests contient des informations détaillées sur ce qui se passe ici: vos en-têtes de demande appID et authorizationkey déclenchent l'envoi par votre navigateur d'un preflight CORS OPTIONS demande avant d'envoyer le GET.

Pour gérer cette requête OPTIONS, vous pouvez installer le package cors npm et suivre les instructions figurant à https://www.npmjs.com/package/cors#enabling-cors-pre-flight pour le configurer:

var express = require('express')
  , cors = require('cors')
  , app = express();
app.options('*', cors()); // include before other routes
app.listen(80, function(){
  console.log('CORS-enabled web server listening on port 80');
});
1
sideshowbarker

La réponse acceptée me donne la solution, je ne me sers pas d'un backend nodeJS, mais bien de Nginx avec php-fpm. 

Mais la réponse explique comment une requête avec en-tête personnalisé doit toujours faire une requête OPTIONS pour vérifier l'acceptation des noms d'en-tête définis. J'ai donc dû modifier la réponse sur le serveur Web pour renvoyer un code 204 avec les en-têtes de droite inclus Sans cela, mon code PHP se trouverait là où l'authentification échouerait et donnerait lieu à un code 403 en raison de l'absence des en-têtes avec le contenu et la méthode de requête utilisés.

Voici ce que j'ai ajouté à l'hôte Nginx pour le faire fonctionner:

location ~ \.php$ {
             add_header 'Access-Control-Allow-Origin' "*";
             add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, DELETE, PUT';
             add_header 'Access-Control-Allow-Headers' 'appID,authorizationkey';

             if ($request_method = 'OPTIONS') {
                return 204;
             }
}

Je sais que c’est loin d’être parfait, mais pour l’instant, cela a fonctionné. et encore merci de m'avoir orienté dans la bonne direction.

3
Steven Bakker