web-dev-qa-db-fra.com

Comment surmonter le problème de la SCRO dans ReactJS

J'essaie de passer un appel d'API via Axios dans mon application React. Cependant, je suis en train d'obtenir ce problème CORS sur mon navigateur. Je me demande si je peux résoudre ce problème du côté client car je n’ai aucun accès à l’API en interne. Le code ci-joint est attaché.

const response = axios({
   method: 'post',
   dataType: 'jsonp',
   url: 'https://awww.api.com',
   data: {
    'appToken':'',
    'request':{ 
        'applicationName':'ddfdf', 
        'userName':'[email protected]', 
        'password':'dfd', 
        'seasonIds':[1521ddfdfd5da02] 
     }
     }
    });
   return{
    type:SHARE_REVIEW,
    payload:'response'
 }
 }

Ci-joint mon WebPack.config.js

module.exports = {

entry: [
'./src/index.js'
 ],
output: {
  path: __dirname,
  publicPath: '/',
  filename: 'bundle.js'
},
module: {
 loaders: [{
  exclude: /node_modules/,
  loader: 'babel',
  query: {
    presets: ['react', 'es2015', 'stage-1']
  }
 },
 { test: /\.json$/, loader: "json-loader"}]
  },
 resolve: {
  extensions: ['', '.js', '.jsx']
 },
devServer: {
historyApiFallback: true,
contentBase: './'
},
node: {
 dns: 'mock',
 net: 'mock'
 },
 };
7
mohan babu

L'idéal serait d'ajouter le support CORS à votre serveur.

Vous pouvez également essayer d’utiliser un module jsonp séparé. Pour autant que je sache, axios ne supporte pas jsonp. Je ne suis donc pas sûr que la méthode que vous utilisez puisse être considérée comme une demande jsonp valide.

Il y a un autre travail astucieux autour du problème de la SCRO. Vous devrez déployer votre code avec un serveur nginx servant de proxy à la fois pour votre serveur et votre client ... La chose qui nous facilitera la tâche avec la directive proxy_pass. Configurez votre serveur nginx de manière à ce que le bloc d’emplacement traitant votre requête particulière proxy_pass ou redirige votre requête vers votre serveur actuel . proxy servant de visage à votre client et à votre serveur, le navigateur est trompé en pensant que le serveur et le client résident dans le même domaine. Ergo no CORS.

Considérons cet exemple.

Votre serveur est my-server.com et votre client est my-client.com Configurez nginx comme suit:

// nginx.conf

upstream server {
    server my-server.com;
}

upstream client {
    server my-client.com;
}

server {
    listen 80;

    server_name my-website.com;
    access_log /path/to/access/log/access.log;
    error_log /path/to/error/log/error.log;

    location / {
        proxy_pass http://client;
    }

    location ~ /server/(?<section>.*) {
        rewrite ^/server/(.*)$ /$1 break;
        proxy_pass http://server;
    }
}

Ici my-website.com sera le nom résultant du site Web où le code sera accessible (nom du site Web proxy) . Une fois que nginx est configuré de cette manière. Vous devrez modifier les demandes de telle sorte que:

  • Tous les appels d'API passent de my-server.com/<API-path> à my-website.com/server/<API-path>

Si vous ne connaissez pas nginx, je vous conseillerais de consulter la documentation .

Pour expliquer en bref ce qui se passe dans la configuration ci-dessus:

  • Les upstreams définissent les serveurs réels vers lesquels les demandes seront redirigées
  • Le bloc server sert à définir le comportement réel du serveur nginx.
  • S'il existe plusieurs blocs serveur, le server_name est utilisé pour identifier le bloc qui sera utilisé pour gérer la requête en cours. 
  • Les directives error_log et access_log permettent de définir les emplacements des fichiers journaux (utilisés pour le débogage).
  • Les blocs location définissent le traitement de différents types de demandes:
    1. Le premier bloc d’emplacement gère toutes les demandes commençant par /; toutes ces demandes sont redirigées vers le client.
    2. Le deuxième bloc d’emplacement gère toutes les demandes commençant par /server/<API-path>. Nous allons rediriger toutes ces demandes vers le serveur.

Remarque: /server est utilisé ici pour distinguer les demandes côté client des demandes côté serveur. Le domaine étant le même, il n’ya pas d’autre moyen de distinguer les demandes. Gardez à l'esprit qu'aucune convention de ce type ne vous oblige à ajouter /server dans tous les cas d'utilisation. Il peut être changé en une autre chaîne, par exemple. /my-server/<API-path>, /abc/<API-path>, etc.

Même si cette technique devrait faire l'affaire, je vous conseillerais vivement d'ajouter le support CORS au serveur, car c'est la manière idéale de gérer des situations de ce type.

Si vous souhaitez éviter tout cela pendant le développement, vous pouvez utiliser l'extension this chrome. Cela devrait vous permettre d'effectuer des requêtes entre domaines au cours du développement.

7
Nahush Farkande

Temporary résoudre ce problème par un plugin chrome appelé CORS. Le serveur principal Btw doit envoyer un en-tête approprié aux demandes frontales. 

6
SaJed

Une autre solution en plus de la réponse de @ Nahush, si vous utilisez déjà Express Framework dans le projet, vous pouvez éviter d'utiliser Nginx pour le reverse-proxy.

Un moyen plus simple consiste à utiliser express-http-proxy

  1. lancez npm run build pour créer le paquet.

    var proxy = require('express-http-proxy');
    
    var app = require('express')();
    
    //define the path of build
    
    var staticFilesPath = path.resolve(__dirname, '..', 'build');
    
    app.use(express.static(staticFilesPath));
    
    app.use('/api/api-server', proxy('www.api-server.com'));
    

Utilisez "/ api/api-server" à partir du code de réaction pour appeler l'API. 

Donc, ce navigateur enverra une demande au même hôte qui sera redirige en interne la demande vers un autre serveur et le navigateur sentira qu’elle provient de la même origine;)

2
niraj

Vous pouvez configurer un serveur proxy express en utilisant http-proxy-middleware pour contourner CORS:

const express = require('express');
const proxy = require('http-proxy-middleware');
const path = require('path');
const port = process.env.PORT || 8080;
const app = express();

app.use(express.static(__dirname));
app.use('/proxy', proxy({
    pathRewrite: {
       '^/proxy/': '/'
    },
    target: 'https://server.com',
    secure: false
}));

app.get('*', (req, res) => {
   res.sendFile(path.resolve(__dirname, 'index.html'));
});

app.listen(port);
console.log('Server started');

À partir de votre application de réaction, toutes les demandes doivent être envoyées à / proxy terminal et elles seront redirigées vers le serveur prévu.

const URL = `/proxy/${PATH}`;
return axios.get(URL);
1
Harshad Ranganathan

la façon la plus simple de trouver un tutoriel de "TraversyMedia" est que il suffit d'utiliser https://cors-anywhere.herokuapp.com dans 'axios' ou 'fetch' api

https://cors-anywhere.herokuapp.com/{type_your_url_here} 

par exemple.

axios.get(`https://cors-anywhere.herokuapp.com/https://www.api.com/`)

et dans votre cas, éditez l'URL comme 

url: 'https://cors-anywhere.herokuapp.com/https://www.api.com',
0
Manoj Sharma