How to overcome the CORS issue in ReactJS

2019-01-11 05:26发布

I am trying to make an API call through Axios in my React Application.However, Iam getting this CORS issue on my browser. I am wondering if i can resolve this issue from a client side as i donot have any access to the API internally.Attached is my code.

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

Attached is my 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'
 },
 };

5条回答
你好瞎i
2楼-- · 2019-01-11 05:39

Temporary solve this issue by a chrome plugin called CORS. Btw backend server have to send proper header to front end requests.

查看更多
虎瘦雄心在
3楼-- · 2019-01-11 05:40

You can set up a express proxy server using http-proxy-middleware to bypass 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');

From your react app all requests should be sent to /proxy endpoint and they will be redirected to the intended server.

const URL = `/proxy/${PATH}`;
return axios.get(URL);
查看更多
爷的心禁止访问
4楼-- · 2019-01-11 05:51

the simplest way what I found from a tutorial of "TraversyMedia" is that just use https://cors-anywhere.herokuapp.com in 'axios' or 'fetch' api

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

e.g.

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

and in your case edit url as

url: 'https://cors-anywhere.herokuapp.com/https://awww.api.com',
查看更多
爷的心禁止访问
5楼-- · 2019-01-11 05:55

Another way besides @Nahush's answer, if you are already using Express framework in the project then you can avoid using Nginx for reverse-proxy.

A simpler way is to use express-http-proxy

  1. run npm run build to create the bundle.

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

Use "/api/api-server" from react code to call the API.

So, that browser will send request to the same host which will be internally redirecting the request to another server and the browser will feel that It is coming from the same origin ;)

查看更多
疯言疯语
6楼-- · 2019-01-11 06:06

The ideal way would be to add CORS support to your server.

You could also try using a separate jsonp module. As far as I know axios does not support jsonp. So I am not sure if the method you are using would qualify as a valid jsonp request.

There is another hackish work around for the CORS problem. You will have to deploy your code with an nginx server serving as a proxy for both your server and your client. The thing that will do the trick us the proxy_pass directive. Configure your nginx server in such a way that the location block handling your particular request will proxy_pass or redirect your request to your actual server. CORS problems usually occur because of change in the website domain. When you have a singly proxy serving as the face of you client and you server, the browser is fooled into thinking that the server and client reside in the same domain. Ergo no CORS.

Consider this example.

Your server is my-server.com and your client is my-client.com Configure nginx as follows:

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

Here my-website.com will be the resultant name of the website where the code will be accessible (name of the proxy website). Once nginx is configured this way. You will need to modify the requests such that:

  • All API calls change from my-server.com/<API-path> to my-website.com/server/<API-path>

In case you are not familiar with nginx I would advise you to go through the documentation.

To explain what is happening in the configuration above in brief:

  • The upstreams define the actual servers to whom the requests will be redirected
  • The server block is used to define the actual behaviour of the nginx server.
  • In case there are multiple server blocks the server_name is used to identify the block which will be used to handle the current request.
  • The error_log and access_log directives are used to define the locations of the log files (used for debugging)
  • The location blocks define the handling of different types of requests:
    1. The first location block handles all requests starting with / all these requests are redirected to the client
    2. The second location block handles all requests starting with /server/<API-path>. We will be redirecting all such requests to the server.

Note: /server here is being used to distinguish the client side requests from the server side requests. Since the domain is the same there is no other way of distinguishing requests. Keep in mind there is no such convention that compels you to add /server in all such use cases. It can be changed to any other string eg. /my-server/<API-path>, /abc/<API-path>, etc.

Even though this technique should do the trick, I would highly advise you to add CORS support to the server as this is the ideal way situations like these should be handled.

If you wish to avoid doing all this while developing you could for this chrome extension. It should allow you to perform cross domain requests during development.

查看更多
登录 后发表回答