Как преодолеть проблему CORS в ReactJS

Я пытаюсь сделать вызов API через Axios в приложении React Application. Однако, я получаю эту проблему CORS в своем браузере. Я задаюсь вопросом, могу ли я решить эту проблему с клиентской стороны, поскольку у меня нет доступа к API внутри. А именно мой код.

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'
 }
 }

В приложении находится мой 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'
 },
 };

Ответ 1

Идеальный способ - добавить поддержку CORS на ваш сервер.

Вы также можете попробовать использовать отдельный модуль jsonp. Насколько я знаю, axios не поддерживает jsonp. Поэтому я не уверен, что метод, который вы используете, будет квалифицирован как допустимый запрос jsonp.

Есть еще одна хакерская работа для решения проблемы CORS. Вы должны будете развернуть свой код на сервере nginx, выступающем в качестве прокси-сервера как для вашего сервера, так и для вашего клиента. То, что поможет нам, - proxy_pass директива proxy_pass. Настройте сервер nginx таким образом, чтобы блок местоположения, обрабатывающий ваш конкретный запрос, proxy_pass или перенаправлял ваш запрос на ваш реальный сервер. Проблемы с CORS обычно возникают из-за изменений в домене сайта. Когда у вас есть один прокси-сервер, который выступает в качестве лица вашего клиента и вашего сервера, браузер обманывается, думая, что сервер и клиент находятся в одном домене. Ergo нет CORS.

Рассмотрим этот пример.

Ваш сервер my-server.com а ваш клиент my-client.com Настройте nginx следующим образом:

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

Здесь my-website.com будет результирующим именем веб-сайта, на котором будет доступен код (имя прокси-сайта). Как только nginx настроен таким образом. Вам нужно будет изменить запросы так, чтобы:

  • Все вызовы API изменяются с my-server.com/<API-path> на my-website.com/server/<API-path>

Если вы не знакомы с nginx, я бы посоветовал вам ознакомиться с документацией.

Чтобы кратко объяснить, что происходит в конфигурации выше:

  • upstream поток определяет фактические серверы, на которые будут перенаправляться запросы.
  • Блок server используется для определения фактического поведения сервера nginx.
  • В случае нескольких блоков серверов server_name используется для идентификации блока, который будет использоваться для обработки текущего запроса.
  • Директивы error_log и access_log используются для определения местоположения файлов журнала (используется для отладки)
  • Блоки location определяют обработку различных типов запросов:
    1. Первый блок местоположения обрабатывает все запросы, начиная с / все эти запросы перенаправляются клиенту
    2. Второй блок местоположения обрабатывает все запросы, начиная с /server/<API-path>. Мы будем перенаправлять все такие запросы на сервер.

Примечание: /server здесь используется, чтобы отличить запросы на стороне клиента от запросов на стороне сервера. Поскольку домен один и тот же, другого способа различения запросов нет. Имейте в виду, что нет такого соглашения, которое заставляет вас добавлять /server во всех таких случаях использования. Его можно изменить на любую другую строку, например. /my-server/<API-path>, /abc/<API-path> и т.д.

Несмотря на то, что этот метод должен сработать, я настоятельно рекомендую вам добавить поддержку CORS на сервер, поскольку это идеальный способ обработки подобных ситуаций.

Если вы хотите избежать всего этого во время разработки, вы можете использовать это расширение для Chrome. Это должно позволить вам выполнять междоменные запросы во время разработки.

Ответ 2

Временно решить эту проблему с помощью хром-плагина под названием CORS. Сервер Btw backend должен посылать правильный заголовок для запросов переднего конца.

Ответ 3

Другой способ, кроме ответа @Nahush: если вы уже используете Express Framework в проекте, тогда вы можете избежать использования Nginx для обратного прокси.

Более простой способ - использовать Express-http-proxy.

  1. запустите npm run build чтобы создать пакет.

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

Используйте "/api/api-server" из кода реакции для вызова API.

Таким образом, этот браузер будет отправлять запрос на тот же хост, который будет внутренне перенаправлять запрос на другой сервер, и браузер будет чувствовать, что он приходит из того же источника;)

Ответ 4

Самый простой способ, который я нашел из учебника "TraversyMedia", заключается в том, что просто используйте https://cors-anywhere.herokuapp.com в api 'axios' или 'fetch'

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

например

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

и в вашем случае измените URL как

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

Ответ 5

Вы можете настроить экспресс-прокси-сервер, используя http-proxy-middleware для обхода 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');

Из вашего приложения реагирования все запросы должны отправляться на конечную точку /proxy, и они будут перенаправлены на нужный сервер.

const URL = '/proxy/${PATH}';
return axios.get(URL);