'Access-Control-Allow-Origin' 从 React(同构应用程序)发出 API 调用时出现问题
'Access-Control-Allow-Origin' issue when API call made from React (Isomorphic app)
我 运行 使用 React 和 Express 的同构 JavaScript 应用程序出现问题。
我正在尝试在我的组件安装时使用 axios.get 发出 HTTP 请求
componentDidMount() {
const url = 'http://ufc-data-api.ufc.com/api/v3/iphone/fighters/title_holders';
axios.get(url).then( res => {
//use res to update current state
})
}
我从 API 获得状态 200 res,但我没有获得任何响应数据并且在我的控制台中出现错误
XMLHttpRequest cannot load http://ufc-data-api.ufc.com/api/v3/iphone/fighters/title_holders.
No 'Access-Control-Allow-Origin' header is present on the requested resource.
Origin 'http://localhost:3000' is therefore not allowed access.
但是,如果我在 server.js
中提出请求
const url = 'http://ufc-data-api.ufc.com/api/v3/iphone/fighters/title_holders';
axios.get(url).then(res => {
//console.log(res);
});
它工作正常,我在服务器启动时得到响应数据。这是实际 API 的问题还是我做错了什么?如果这是一个 CORS 问题,我猜 server.js 中的请求也不会起作用?谢谢!
因为服务器没有CORS header,所以你不能得到响应。
这是我从 Chrome 浏览器捕获的 API 中的 header:
Age:28
Cache-Control:max-age=3600, public
Connection:keep-alive
Date:Fri, 06 Jan 2017 02:05:33 GMT
ETag:"18303ae5d3714f8f1fbcb2c8e6499190"
Server:Cowboy
Status:200 OK
Via:1.1 vegur, 1.1 e01a35c1b8f382e5c0a399f1741255fd.cloudfront.net (CloudFront)
X-Amz-Cf-Id:GH6w6y_P5ht7AqAD3SnlK39EJ0PpnignqSI3o5Fsbi9PKHEFNMA0yw==
X-Cache:Hit from cloudfront
X-Content-Type-Options:nosniff
X-Frame-Options:SAMEORIGIN
X-Request-Id:b971e55f-b43d-43ce-8d4f-aa9d39830629
X-Runtime:0.014042
X-Ua-Compatible:chrome=1
X-Xss-Protection:1; mode=block
没有 CORS header 响应 headers.
CORS 是 浏览器 的一项功能。服务器需要选择加入 CORS 以允许浏览器绕过同源策略。您的服务器不会有相同的限制,并且能够向任何带有 public API 的服务器发出请求。 https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS
在您的服务器上创建一个启用了 CORS 的端点,它可以充当您的 Web 应用程序的代理。
我认为你的问题的答案是
To have Chrome send Access-Control-Allow-Origin in the header, just alias your localhost in your /etc/hosts file to some other domain, like:
127.0.0.1 localhost yourdomain.com
使用名为 Allow-Control-Allow-Origin: * 的 google Chrome 扩展。它会在您的应用程序中即时修改 CORS headers。
我不知道这是否有帮助,但我在远程调试 react-native 应用程序时遇到了同样的错误。我是 运行 192.168.x.x:8081 上的调试器。我阅读了一些关于此 Cross-Origin Resource Sharing (CORS) 的内容,以了解什么是 CORS。 (我是初学者)并将我的 URL 从 IP:8081 更改为 localhost:8081,我的问题就解决了。
我遇到了同样的问题。其他答案是正确的,但还有另一种解决方案。
您可以设置响应 header 以允许 cross-origin 访问。
根据 this post,您必须在任何 app.get 调用之前添加以下代码:
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "X-Requested-With");
next();
});
这对我有用:)
我今天遇到了同样的错误,使用带有 Typescript 的 React 和使用 Java Spring 启动的后端,如果你有后端的手,你可以简单地添加一个配置CORS 文件。
对于下面的示例,我将允许的原点设置为 * 以允许所有但您可以更具体地设置 url,例如 http://localhost:3000。
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
@Configuration
public class AppCorsConfiguration {
@Bean
public FilterRegistrationBean corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("*");
config.addAllowedHeader("*");
config.addAllowedMethod("*");
source.registerCorsConfiguration("/**", config);
FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
bean.setOrder(0);
return bean;
}
}
我在使用 fetch
命令时遇到了同样的问题。快速浏览 here 的文档告诉我们:
If the server you are requesting from doesn't support CORS, you should get an error in the console indicating that the cross-origin request is blocked due to the CORS Access-Control-Allow-Origin header being missing.
您可以使用no-cors模式来请求不透明的资源。
fetch('https://bar.com/data.json', {
mode: 'no-cors' // 'cors' by default
})
.then(function(response) {
// Do something with response
});
//install cors using terminal/command
$ npm install cors
//If your using express in your node server just add
var cors = require('cors');
app.use(cors())
//and re-run the server, your problem is rectified][1]][1]
**If you won't be understood then see below image**
https://i.stack.imgur.com/Qeqmc.png
不使用外部代理或 Chrome 扩展程序进行修复
应该在服务器端启用 CORS!如果你不能在服务器上激活它(例如使用外部 API)创建一个中间件 React -> Middleware -> Orginal Server
.
创建一个 Node.js 项目(中间件)并在 app.js
.
中使用以下代码
const express = require("express");
var cors = require('cors')
const app = express();
app.use(cors());
const { createProxyMiddleware } = require('http-proxy-middleware');
app.use('/api', createProxyMiddleware({
target: 'http://localhost:8080/', //original url
changeOrigin: true,
//secure: false,
onProxyRes: function (proxyRes, req, res) {
proxyRes.headers['Access-Control-Allow-Origin'] = '*';
}
}));
app.listen(5000);
这会将请求 http://localhost:5000/api/xxx
传递给原始服务器(例如 http://localhost:8080/api/xxx
),并将结果 returns 传递给客户端。
更改客户端(React)调用proxy获取数据无CORS错误(只需要更改url中的端口):
axios.get('http://localhost:5000/api/xxx', //proxy uri
{
headers: {
authorization: ' xxxxxxxxxx' ,
'Content-Type': 'application/json'
}
}).then(function (response) {
console.log(response);
});
运行 节点项目 node app.js
和 React 项目 npm start
.
在调试模式下使用 vs code 时可以使用此代码。
"runtimeArgs": ["--disable-web-security","--user-data-dir=~/ChromeUserData/"]
launch.json
{
"version": "0.2.0",
"configurations": [
{
"type": "chrome",
"request": "launch",
"name": "Chrome disable-web-security",
"url": "http://localhost:3000",
"webRoot": "${workspaceFolder}",
"runtimeArgs": [
"--disable-web-security",
"--user-data-dir=~/ChromeUserData/"
]
}
]
}
或直接运行
Chrome --disable-web-security --user-data-dir=~/ChromeUserData/
Create-React-App 有一个简单的方法来处理这个问题:在 package.json 文件中添加一个代理字段,如下所示
"proxy": "http://localhost:8081",
在我的例子中,即使在服务器端启用它之后,我仍然收到 CORS 错误。问题是 url。 localhost:4001/todos
我忘了在前面加上 'http'。
http://localhost:4001/todos //correct way
您不必在客户端处理它。只需要以下步骤:
第 1 步:
npm install cors
第 2 步:
//express-server.js
...
const cors = require('cors');
app.use(cors());
完成!
当您尝试通过 React 应用程序调用端点时,这是一个常见问题,因为 React 应用程序在 localhost:3000 上 运行,而 apis 在不同的服务器上。
纠正这个错误安装'http-proxy-middleware'
npm i http-proxy-middleware
or
yarn add http-proxy-middleware
安装后在 src[=30 中创建一个 setupProxy.js =]文件夹
并遵循以下代码
const { createProxyMiddleware } = require('http-proxy-middleware');
module.exports = function(app) {
app.use(
'/getDetails', //this is your api
createProxyMiddleware({
target:'http://10.0.0.20:9000/getDetails', //this is your whole endpoint link
changeOrigin: true,
})
);
app.use(
'/getproducts', //this is your api
createProxyMiddleware({
target:'http://10.0.0.20:9000/getproducts', //this is your whole endpoint link
changeOrigin: true,
})
);
};
您可以在 app.use 中添加任意数量的 api。
然后通常调用 api
axios.get('http://10.0.0.20:9680/getDetails')
有关更多详细信息,请查看下方 link
Porxying API requests in Development in React JS
将代理添加到 package.json 文件并将 url 的剩余部分保留在提取本身中。
例如
在package.json文件中,
"proxy" : "https://www.google.com", //添加自己的网站link
在 App.js 文件中
const response = await fetch(./...(根据你自己的))
我 运行 使用 React 和 Express 的同构 JavaScript 应用程序出现问题。
我正在尝试在我的组件安装时使用 axios.get 发出 HTTP 请求
componentDidMount() {
const url = 'http://ufc-data-api.ufc.com/api/v3/iphone/fighters/title_holders';
axios.get(url).then( res => {
//use res to update current state
})
}
我从 API 获得状态 200 res,但我没有获得任何响应数据并且在我的控制台中出现错误
XMLHttpRequest cannot load http://ufc-data-api.ufc.com/api/v3/iphone/fighters/title_holders.
No 'Access-Control-Allow-Origin' header is present on the requested resource.
Origin 'http://localhost:3000' is therefore not allowed access.
但是,如果我在 server.js
中提出请求const url = 'http://ufc-data-api.ufc.com/api/v3/iphone/fighters/title_holders';
axios.get(url).then(res => {
//console.log(res);
});
它工作正常,我在服务器启动时得到响应数据。这是实际 API 的问题还是我做错了什么?如果这是一个 CORS 问题,我猜 server.js 中的请求也不会起作用?谢谢!
因为服务器没有CORS header,所以你不能得到响应。
这是我从 Chrome 浏览器捕获的 API 中的 header:
Age:28
Cache-Control:max-age=3600, public
Connection:keep-alive
Date:Fri, 06 Jan 2017 02:05:33 GMT
ETag:"18303ae5d3714f8f1fbcb2c8e6499190"
Server:Cowboy
Status:200 OK
Via:1.1 vegur, 1.1 e01a35c1b8f382e5c0a399f1741255fd.cloudfront.net (CloudFront)
X-Amz-Cf-Id:GH6w6y_P5ht7AqAD3SnlK39EJ0PpnignqSI3o5Fsbi9PKHEFNMA0yw==
X-Cache:Hit from cloudfront
X-Content-Type-Options:nosniff
X-Frame-Options:SAMEORIGIN
X-Request-Id:b971e55f-b43d-43ce-8d4f-aa9d39830629
X-Runtime:0.014042
X-Ua-Compatible:chrome=1
X-Xss-Protection:1; mode=block
没有 CORS header 响应 headers.
CORS 是 浏览器 的一项功能。服务器需要选择加入 CORS 以允许浏览器绕过同源策略。您的服务器不会有相同的限制,并且能够向任何带有 public API 的服务器发出请求。 https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS
在您的服务器上创建一个启用了 CORS 的端点,它可以充当您的 Web 应用程序的代理。
我认为你的问题的答案是
To have Chrome send Access-Control-Allow-Origin in the header, just alias your localhost in your /etc/hosts file to some other domain, like:
127.0.0.1 localhost yourdomain.com
使用名为 Allow-Control-Allow-Origin: * 的 google Chrome 扩展。它会在您的应用程序中即时修改 CORS headers。
我不知道这是否有帮助,但我在远程调试 react-native 应用程序时遇到了同样的错误。我是 运行 192.168.x.x:8081 上的调试器。我阅读了一些关于此 Cross-Origin Resource Sharing (CORS) 的内容,以了解什么是 CORS。 (我是初学者)并将我的 URL 从 IP:8081 更改为 localhost:8081,我的问题就解决了。
我遇到了同样的问题。其他答案是正确的,但还有另一种解决方案。 您可以设置响应 header 以允许 cross-origin 访问。 根据 this post,您必须在任何 app.get 调用之前添加以下代码:
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "X-Requested-With");
next();
});
这对我有用:)
我今天遇到了同样的错误,使用带有 Typescript 的 React 和使用 Java Spring 启动的后端,如果你有后端的手,你可以简单地添加一个配置CORS 文件。
对于下面的示例,我将允许的原点设置为 * 以允许所有但您可以更具体地设置 url,例如 http://localhost:3000。
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
@Configuration
public class AppCorsConfiguration {
@Bean
public FilterRegistrationBean corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("*");
config.addAllowedHeader("*");
config.addAllowedMethod("*");
source.registerCorsConfiguration("/**", config);
FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
bean.setOrder(0);
return bean;
}
}
我在使用 fetch
命令时遇到了同样的问题。快速浏览 here 的文档告诉我们:
If the server you are requesting from doesn't support CORS, you should get an error in the console indicating that the cross-origin request is blocked due to the CORS Access-Control-Allow-Origin header being missing.
您可以使用no-cors模式来请求不透明的资源。
fetch('https://bar.com/data.json', {
mode: 'no-cors' // 'cors' by default
})
.then(function(response) {
// Do something with response
});
//install cors using terminal/command
$ npm install cors
//If your using express in your node server just add
var cors = require('cors');
app.use(cors())
//and re-run the server, your problem is rectified][1]][1]
**If you won't be understood then see below image**
https://i.stack.imgur.com/Qeqmc.png
不使用外部代理或 Chrome 扩展程序进行修复
应该在服务器端启用 CORS!如果你不能在服务器上激活它(例如使用外部 API)创建一个中间件 React -> Middleware -> Orginal Server
.
创建一个 Node.js 项目(中间件)并在
中使用以下代码app.js
.const express = require("express"); var cors = require('cors') const app = express(); app.use(cors()); const { createProxyMiddleware } = require('http-proxy-middleware'); app.use('/api', createProxyMiddleware({ target: 'http://localhost:8080/', //original url changeOrigin: true, //secure: false, onProxyRes: function (proxyRes, req, res) { proxyRes.headers['Access-Control-Allow-Origin'] = '*'; } })); app.listen(5000);
这会将请求 http://localhost:5000/api/xxx
传递给原始服务器(例如 http://localhost:8080/api/xxx
),并将结果 returns 传递给客户端。
更改客户端(React)调用proxy获取数据无CORS错误(只需要更改url中的端口):
axios.get('http://localhost:5000/api/xxx', //proxy uri { headers: { authorization: ' xxxxxxxxxx' , 'Content-Type': 'application/json' } }).then(function (response) { console.log(response); });
运行 节点项目
node app.js
和 React 项目npm start
.
在调试模式下使用 vs code 时可以使用此代码。
"runtimeArgs": ["--disable-web-security","--user-data-dir=~/ChromeUserData/"]
launch.json
{
"version": "0.2.0",
"configurations": [
{
"type": "chrome",
"request": "launch",
"name": "Chrome disable-web-security",
"url": "http://localhost:3000",
"webRoot": "${workspaceFolder}",
"runtimeArgs": [
"--disable-web-security",
"--user-data-dir=~/ChromeUserData/"
]
}
]
}
或直接运行
Chrome --disable-web-security --user-data-dir=~/ChromeUserData/
Create-React-App 有一个简单的方法来处理这个问题:在 package.json 文件中添加一个代理字段,如下所示
"proxy": "http://localhost:8081",
在我的例子中,即使在服务器端启用它之后,我仍然收到 CORS 错误。问题是 url。 localhost:4001/todos
我忘了在前面加上 'http'。
http://localhost:4001/todos //correct way
您不必在客户端处理它。只需要以下步骤:
第 1 步:
npm install cors
第 2 步:
//express-server.js
...
const cors = require('cors');
app.use(cors());
完成!
当您尝试通过 React 应用程序调用端点时,这是一个常见问题,因为 React 应用程序在 localhost:3000 上 运行,而 apis 在不同的服务器上。
纠正这个错误安装'http-proxy-middleware'
npm i http-proxy-middleware
or
yarn add http-proxy-middleware
安装后在 src[=30 中创建一个 setupProxy.js =]文件夹
并遵循以下代码
const { createProxyMiddleware } = require('http-proxy-middleware');
module.exports = function(app) {
app.use(
'/getDetails', //this is your api
createProxyMiddleware({
target:'http://10.0.0.20:9000/getDetails', //this is your whole endpoint link
changeOrigin: true,
})
);
app.use(
'/getproducts', //this is your api
createProxyMiddleware({
target:'http://10.0.0.20:9000/getproducts', //this is your whole endpoint link
changeOrigin: true,
})
);
};
您可以在 app.use 中添加任意数量的 api。 然后通常调用 api
axios.get('http://10.0.0.20:9680/getDetails')
有关更多详细信息,请查看下方 link Porxying API requests in Development in React JS
将代理添加到 package.json 文件并将 url 的剩余部分保留在提取本身中。
例如
在package.json文件中, "proxy" : "https://www.google.com", //添加自己的网站link
在 App.js 文件中 const response = await fetch(./...(根据你自己的))