如何克服ReactJS中的CORS问题

时间:2017-04-18 02:01:07

标签: javascript reactjs cors redux axios

我正在尝试通过我的React Application中的Axios进行API调用。但是,我在浏览器上遇到了这个CORS问题。我想知道我是否可以从客户端解决此问题,因为我无法在内部访问API .Attached是我的代码。

const response = axios({
   method: 'post',
   dataType: 'jsonp',
   url: 'https://awww.api.com',
   data: {
    'appToken':'',
    'request':{ 
        'applicationName':'ddfdf', 
        'userName':'jaime@dfd.com', 
        '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'
 },
 };

9 个答案:

答案 0 :(得分:7)

理想的方法是为您的服务器添加CORS支持。

您也可以尝试使用单独的jsonp模块。据我所知,axios不支持jsonp。所以我不确定你使用的方法是否符合有效的jsonp请求。

还有另一个关于CORS问题的黑客工作。您必须使用nginx服务器部署代码,该服务器充当服务器和客户端的代理。 我会用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,我建议您浏览documentation

简要说明上述配置中发生的事情:

  • upstream定义请求将被重定向到的实际服务器
  • server块用于定义nginx服务器的实际行为。
  • 如果有多个服务器块,server_name用于标识将用于处理当前请求的块。
  • error_logaccess_log指令用于定义日志文件的位置(用于调试)
  • location块定义了对不同类型请求的处理:
    1. 第一个位置块处理以/开头的所有请求被重定向到客户端的所有请求
    2. 第二个位置块处理以/server/<API-path>开头的所有请求。我们将把所有这些请求重定向到服务器。

注意:此处/server用于区分客户端请求和服务器端请求。由于域是相同的,因此没有其他方法可以区分请求。请记住,没有这样的约定迫使您在所有此类用例中添加/server。它可以更改为任何其他字符串,例如。 /my-server/<API-path>/abc/<API-path>

尽管这种技术可以解决问题,但我强烈建议您将CORS支持添加到服务器,因为这是理想的方式,应该处理这类情况。

如果您希望在开发过程中避免这样做,可以this chrome扩展。它应该允许您在开发期间执行跨域请求。

答案 1 :(得分:6)

通过名为CORS的chrome插件临时解决此问题。顺便说一下后端服务器必须向前端请求发送正确的标头。

答案 2 :(得分:3)

您可以让您的React开发服务器将您的请求代理到该服务器。只需将您的请求发送到本地服务器,就像这样:url: "/" 并将以下行添加到您的package.json文件中

"proxy": "https://awww.api.com"

尽管如果您要将CORS请求发送到多个来源,则必须自己手动配置代理 此链接将帮助您设置Create React App Proxying API requests

答案 3 :(得分:2)

除了 Nahush 的答案之外的另一种方法,如果您已经在项目中使用 Express框架,那么您可以避免使用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'));
    
  2. 使用&#34; / api / api-server&#34;从反应代码调用API。

      

    因此,该浏览器将向同一主机发送请求   在内部将请求重定向到另一台服务器,浏览器会觉得它来自同一个来源;)

答案 4 :(得分:2)

从“ TraversyMedia”教程中发现的最简单的方法是 只需在'axios'或'fetch'api中使用https://cors-anywhere.herokuapp.com

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

例如

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

,在您的情况下,将网址编辑为

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

答案 5 :(得分:2)

您的服务器端代码肯定缺少 Cors 支持。在 Asp.net core 中,您可以按照以下方式进行。 在 public void ConfigureServices(IServiceCollection services) 中添加以下调用 在 Startup.cs 文件中。

public void ConfigureServices(IServiceCollection services)
{
     app.UseCors(options => 
                options.WithOrigins("http://localhost:3000").AllowAnyHeader().AllowAnyMethod());
}
        

答案 6 :(得分:1)

您可以使用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);

答案 7 :(得分:0)

在“我的情况”中添加chrome Cross Domain-CORS扩展名可以解决所有问题。您可以尝试使用它,希望对您有所帮助...。

答案 8 :(得分:0)

正如@Nahush 已经指出的,这实际上是一个服务器问题,而不是应该在客户端处理的问题。服务器应该为 Access-Control-Allow-Origin: 添加标头 参考 - https://www.w3.org/wiki/CORS_Enabled#How_can_I_participate.3F

在这里,如果您的服务器使用 express 框架,我只是在服务器端添加一种更简单的方法来执行此操作。使用 express CORS Middleware 是一个 2 行代码解决方案。

安装使用 -

npm install -S cors

将以下代码添加到您的后端应用中。

import cors from 'cors';
app.use(cors());

大功告成。