如何克服ReactJS中的CORS问题

moh*_*abu 9 javascript cors reactjs redux axios

我试图在我的React Application中通过Axios进行API调用.但是,我在浏览器上遇到了这个CORS问题.我想知道我是否可以从客户端解决此问题,因为我内部没有任何API访问权限.附件是我的代码.

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'
 }
 }
Run Code Online (Sandbox Code Playgroud)

附件是我的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'
 },
 };
Run Code Online (Sandbox Code Playgroud)

小智 8

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

"proxy": "https://awww.api.com"
Run Code Online (Sandbox Code Playgroud)

不过,如果您将 CORS 请求发送到多个源,则必须自己手动配置代理此链接将帮助您设置创建 React App 代理 API 请求


Nah*_*nde 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;
    }
}
Run Code Online (Sandbox Code Playgroud)

my-website.com将是可访问代码的网站的结果名称(代理网站的名称).一旦nginx以这种方式配置.您需要修改请求,以便:

  • 所有API调用都从更改my-server.com/<API-path>my-website.com/server/<API-path>

如果您不熟悉nginx,我建议您阅读文档.

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

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

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

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

如果您希望在开发时避免这样做,可以使用 chrome扩展.它应该允许您在开发期间执行跨域请求.


nir*_*raj 7

除了@ 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'));
    
    Run Code Online (Sandbox Code Playgroud)

使用反应代码中的“/api/api-server”来调用 API。

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


Saj*_*jed 6

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

  • 这就像一个魅力。如果您只想测试并启动并运行某些东西,这非常有帮助。我使用了 Moesif Origin &amp; CORS Changer 插件。只要打开它就可以了! (2认同)

Man*_*rma 6

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

https://cors-anywhere.herokuapp.com/{type_your_url_here} 
Run Code Online (Sandbox Code Playgroud)

例如

axios.get(`https://cors-anywhere.herokuapp.com/https://www.api.com/`)
Run Code Online (Sandbox Code Playgroud)

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

url: 'https://cors-anywhere.herokuapp.com/https://www.api.com',
Run Code Online (Sandbox Code Playgroud)

  • Herokuapp“Cors Anywhere”是一个演示版,速度非常慢,因此无法在生产实时应用程序上使用。 (3认同)
  • 您永远不想在生产应用程序中执行此操作。正如@Manish 指出的,安全隐患是显而易见的。除此之外,您将应用程序的性能限制为第三方能够处理的任何内容。您的应用程序也会在出现故障时出现故障,并在 url 更改时失败等。请不要这样做。 (3认同)
  • 神圣的#%$ 这有效!我的日子得救了,你能解释一下这是在做什么吗? (2认同)
  • CORS-Anywhere HerokuApp 提供了一个代理来传递我们的请求及其标头。您可以在 https://cors-anywhere.herokuapp.com 上了解更多信息,更多解释请访问媒体的帖子- https://medium.com/netscape/hacking-it-out-when-cors-wont-let-you- be-great-35f6206cc646 (2认同)
  • 请注意,这会导致您的所有API请求都通过第三方应用程序传递,这绝对不是一个好的安全习惯。 (2认同)