Javascript 如何克服 ReactJS 中的 CORS 问题
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/43462367/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to overcome the CORS issue in ReactJS
提问by mohan babu
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.
我正在尝试通过我的 React 应用程序中的 Axios 进行 API 调用。但是,我在浏览器上遇到了这个 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'
}
}
Attached is my WebPack.config.js
附上我的 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'
},
};
采纳答案by Nahush Farkande
The ideal way would be to add CORS support to your server.
理想的方法是为您的服务器添加 CORS 支持。
You could also try using a separate jsonpmodule. 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.
您也可以尝试使用单独的jsonp模块。据我所知 axios 不支持 jsonp。所以我不确定您使用的方法是否符合有效的 jsonp 请求。
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_passdirective. Configure your nginx server in such a way that the location block handling your particular request will proxy_passor 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.
对于 CORS 问题,还有另一种骇人听闻的解决方法。您必须使用 nginx 服务器部署您的代码,作为您的服务器和客户端的代理。可以欺骗我们proxy_pass指令的东西。以这样的方式配置您的 nginx 服务器,以便处理您的特定请求的位置块将proxy_pass或将您的请求重定向到您的实际服务器。CORS 问题通常是由于网站域的变化而发生的。当您有一个单独的代理作为客户端和服务器的面孔时,浏览器会误以为服务器和客户端驻留在同一个域中。因此没有 CORS。
Consider this example.
考虑这个例子。
Your server is my-server.comand your client is my-client.comConfigure nginx as follows:
您的服务器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/(.*)$ / break;
proxy_pass http://server;
}
}
Here my-website.comwill 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:
这my-website.com将是可访问代码的网站的结果名称(代理网站的名称)。一旦以这种方式配置了 nginx。您将需要修改请求,以便:
- All API calls change from
my-server.com/<API-path>tomy-website.com/server/<API-path>
- 所有 API 调用都从
my-server.com/<API-path>变为my-website.com/server/<API-path>
In case you are not familiar with nginx I would advise you to go through the documentation.
如果您不熟悉 nginx,我建议您阅读文档。
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
serverblock is used to define the actual behaviour of the nginx server. - In case there are multiple server blocks the
server_nameis used to identify the block which will be used to handle the current request. - The
error_logandaccess_logdirectives are used to define the locations of the log files (used for debugging) - The
locationblocks define the handling of different types of requests:- The first location block handles all requests starting with
/all these requests are redirected to the client - The second location block handles all requests starting with
/server/<API-path>. We will be redirecting all such requests to the server.
- The first location block handles all requests starting with
- 在
upstream小号定义实际的服务器向谁请求将被重定向 - 该
server块用于定义 nginx 服务器的实际行为。 - 如果有多个服务器块,
server_name则用于标识将用于处理当前请求的块。 - 在
error_log和access_log指令用于定义日志文件的位置(用于调试) - 这些
location块定义了对不同类型请求的处理:- 第一个位置块处理所有请求,
/所有这些请求都被重定向到客户端 - 第二个位置块处理所有以 开头的请求
/server/<API-path>。我们会将所有此类请求重定向到服务器。
- 第一个位置块处理所有请求,
Note: /serverhere 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 /serverin all such use cases. It can be changed to any other string eg. /my-server/<API-path>, /abc/<API-path>, etc.
注意:/server这里用于区分客户端请求和服务器端请求。由于域相同,因此没有其他方法可以区分请求。请记住,没有这样的约定迫使您添加/server所有此类用例。它可以更改为任何其他字符串,例如。/my-server/<API-path>,/abc/<API-path>等等。
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.
尽管这种技术应该可以解决问题,但我强烈建议您向服务器添加 CORS 支持,因为这是处理此类情况的理想方式。
If you wish to avoid doing all this while developing you could for thischrome extension. It should allow you to perform cross domain requests during development.
如果您希望在开发时避免执行所有这些操作,则可以使用此chrome 扩展。它应该允许您在开发期间执行跨域请求。
回答by Manoj Sharma
the simplest way what I found from a tutorial of "TraversyMedia" is that just use https://cors-anywhere.herokuapp.comin 'axios' or 'fetch' api
我从“TraversyMedia”教程中发现的最简单的方法是在“axios”或“fetch”api中使用https://cors-anywhere.herokuapp.com
https://cors-anywhere.herokuapp.com/{type_your_url_here}
e.g.
例如
axios.get(`https://cors-anywhere.herokuapp.com/https://www.api.com/`)
and in your case edit url as
在你的情况下,将 url 编辑为
url: 'https://cors-anywhere.herokuapp.com/https://www.api.com',
回答by Sajed
Temporary solve this issue by a chrome plugin called CORS. Btw backend server have to send proper header to front end requests.
通过一个名为 CORS 的 chrome 插件临时解决了这个问题。顺便说一句,后端服务器必须向前端请求发送正确的标头。
回答by niraj
Another way besides @Nahush's answer, if you are already using Express frameworkin the project then you can avoid using Nginx for reverse-proxy.
除了@ Nahush的回答之外的另一种方式,如果您已经在项目中使用Express 框架,那么您可以避免使用 Nginx 进行反向代理。
A simpler way is to use express-http-proxy
更简单的方法是使用express-http-proxy
run
npm run buildto 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'));
运行
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'));
Use "/api/api-server" from react code to call the API.
使用反应代码中的“/api/api-server”来调用 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 ;)
因此,该浏览器会将请求发送到同一主机,该主机将在内部将请求重定向到另一台服务器,浏览器会觉得它来自同一来源;)
回答by Harshad Ranganathan
You can set up a express proxy server using http-proxy-middlewareto bypass CORS:
您可以使用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');
From your react app all requests should be sent to /proxyendpoint and they will be redirected to the intended server.
从您的反应应用程序中,所有请求都应发送到/proxy端点,它们将被重定向到预期的服务器。
const URL = `/proxy/${PATH}`;
return axios.get(URL);

