使用 Axios 的访问控制来源 Header 错误
Access Control Origin Header error using Axios
我正在 React Web 应用程序中使用 Axios 进行 API 调用。但是,我在 Chrome:
中收到此错误
XMLHttpRequest cannot load
https://example.restdb.io/rest/mock-data. No
'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'http://localhost:8080' is therefore not allowed
access.
{
axios
.get("https://example.restdb.io/rest/mock-data", {
headers: {
"x-apikey": "API_KEY",
},
responseType: "json",
})
.then((response) => {
this.setState({ tableData: response.data });
});
}
我也在 Stack Overflow 上阅读了关于同一问题的几个答案,标题为 Access-Control-Allow-Origin
但仍然无法弄清楚如何解决这个问题。我不想在 Chrome 中使用扩展名或使用临时 hack 来解决这个问题。请提出解决上述问题的标准方法。
在尝试了几个答案后,我尝试了这个,
headers: {
'x-apikey': '59a7ad19f5a9fa0808f11931',
'Access-Control-Allow-Origin' : '*',
'Access-Control-Allow-Methods':'GET,PUT,POST,DELETE,PATCH,OPTIONS',
},
现在我得到的错误是,
Request header field Access-Control-Allow-Origin is not
allowed by Access-Control-Allow-Headers in preflight response
如果你的后端支持 CORS,你可能需要在你的请求中添加这个 header:
headers: {"Access-Control-Allow-Origin": "*"}
[更新] Access-Control-Allow-Origin 是一个响应 header - 所以为了启用 CORS - 你需要将此 header 添加到服务器的响应中。
但在大多数情况下,更好的解决方案是配置 reverse proxy,以便您的服务器能够将请求从前端重定向到后端,而无需启用 CORS。
您可以在此处找到有关 CORS 机制的文档:
https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS
在请求中使用 Access-Control-Allow-Origin header 在这种情况下对您没有帮助,而此 header 只能用于响应...
要使其正常工作,您可能应该将此 header 添加到您的 response.You 中,也可以尝试将 header crossorigin:true
添加到您的请求中。
据我了解,问题是请求从 localhost:3000 发送到 localhost:8080,而浏览器拒绝诸如 CORS 之类的请求。所以解决方案是创建代理
我的解决方案是:
import proxy from 'http-proxy-middleware'
app.use('/api/**', proxy({ target: "http://localhost:8080" }));
在节点js(后端)中,使用cors npm模块
$ npm install cors
然后添加这些行来支持Access-Control-Allow-Origin,
const express = require('express')
const app = express()
app.use(cors())
app.get('/products/:id', cors(), function (req, res, next) {
res.json({msg: 'This is CORS-enabled for a Single Route'});
});
您可以实现相同的效果,无需任何外部模块
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
我遇到了类似的问题,我发现在我的情况下,请求中的 withCredentials: true
正在激活 CORS 检查,而在 header 中发出相同的请求将避免检查:
Reason: expected ‘true’ in CORS header ‘Access-Control-Allow-Credentials’
不使用
withCredentials: true
但设置
'Access-Control-Allow-Credentials':true
在 header 秒。
},
"proxy": "http://localhost:8080",
"devDependencies": {
在package.json
中使用代理
$ npm install cors
从 npm 安装 cors 后,将以下代码添加到您的节点应用程序文件中。它解决了我的问题。
var express = require('express')
var cors = require('cors')
var app = express()
app.use(cors())
首先,CORS 绝对是服务器端问题而不是客户端问题,但我非常确定服务器代码在我的情况下是正确的,因为其他应用程序在不同域上使用同一服务器工作。此解决方案在其他答案中有更详细的描述。
当我开始对我的自定义实例使用 axios
时,我的问题就出现了。就我而言,这是一个非常具体的问题,当我们在 axios
实例中使用 baseURL 然后尝试从任何地方进行 GET
或 POST
调用时,axios 添加了一个baseURL 和请求 URL 之间的斜杠 /。这也有道理,但这是隐藏的问题。我的 Laravel 服务器正在重定向以删除导致此问题的尾部斜杠。
通常,飞行前 OPTIONS
请求不喜欢重定向。如果您的服务器使用 301 状态代码进行重定向,则它可能被缓存在不同的级别。所以,一定要检查并避免它。
我有同样的错误。我使用 npm i cors
在后端安装 CORS 解决了这个问题。然后您需要将此添加到您的代码中:
const cors = require('cors');
app.use(cors());
这帮我修好了;现在我可以使用 AJAX post 我的表单,而无需添加任何自定义的 headers.
我在尝试创建 React Axios 实例时遇到了类似的问题。
我使用以下方法解决了它。
const instance = axios.create({
baseURL: "https://jsonplaceholder.typicode.com/",
withCredentials: false,
headers: {
'Access-Control-Allow-Origin' : '*',
'Access-Control-Allow-Methods':'GET,PUT,POST,DELETE,PATCH,OPTIONS',
}
});
试试代理
package.json 添加代码:
"proxy":"https://localhost:port"
并重启 npm enjoy
相同的代码
const instance = axios.create({
baseURL: "/api/list",
});
npm i cors
const app = require('express')()
app.use(cors())
以上代码对我有用。
我将着手解决这个复杂的问题。
什么是来源?
来源本身就是主机名(方案、主机名和端口)i.g。 https://www.google.com
或者可以是本地打开的文件 file://
等。它是某些东西(i.g。网页)的来源。当您打开网络浏览器并转到 https://www.google.com
时,显示给您的网页的来源是 https://www.google.com
。您可以在 Chrome Dev Tools under Security
:
中看到这一点
如果您通过文件资源管理器(不通过服务器提供服务)打开本地 HTML 文件,同样适用:
这与 CORS 问题有什么关系?
当您打开浏览器并转到 https://website.com
时,该网站将具有 https://website.com
的来源。该网站将 很可能只会 获取图像、图标、js 文件并对 https://website.com
进行 API 调用,基本上它调用的是与从中提供服务的服务器相同的服务器. 同源调用.
如果您打开网络浏览器并打开本地 HTML 文件,并且在该 html 文件中有 javascript 想要向 google 发出请求例如,您收到以下错误:
same-origin 策略告诉浏览器阻止 cross-origin 请求。在这种情况下,origin null
正在尝试向 https://www.google.com
发出请求(cross-origin 请求)。由于设置了 CORS 策略,浏览器将不允许这样做,并且该策略是不允许 cross-origin 请求。
如果我的页面是从本地主机上的服务器提供的,同样适用:
本地主机服务器示例
如果我们使用以下代码在 localhost:3000 上托管我们自己的本地主机 API 服务器 运行:
const express = require('express')
const app = express()
app.use(express.static('public'))
app.get('/hello', function (req, res) {
// res.header("Access-Control-Allow-Origin", "*");
res.send('Hello World');
})
app.listen(3000, () => {
console.log('alive');
})
然后从文件资源管理器打开一个 HTML 文件(向 localhost:3000 服务器发出请求)目录,将发生以下错误:
由于网页不是从 localhost:3000 上的本地主机服务器提供的,并且通过文件资源管理器,来源与服务器 API 来源不同,因此 cross-origin正在尝试请求。由于 CORS 策略,浏览器正在停止此尝试。
但是如果我们取消注释行:
const express = require('express')
const app = express()
app.use(express.static('public'))
app.get('/hello', function (req, res) {
res.header("Access-Control-Allow-Origin", "*");
res.send('Hello World');
})
app.listen(3000, () => {
console.log('alive');
})
现在再试一次:
它起作用了,因为发送 HTTP 响应的服务器现在包含一个 header 说明 cross-origin 请求可以发生在服务器上,这意味着浏览器会允许它发生,因此没有错误。
如何解决问题(以下之一)
- 从与您发出的请求所在的相同来源(同一主机)提供页面。
- 通过在响应 headers 中明确声明允许服务器接收 cross-origin 请求。
- 如果使用 NGINX 等反向代理,请将 NGINX 配置为发送允许 CORS 的响应 header。
- 不要使用浏览器。例如,使用 cURL,它不像浏览器那样关心 CORS 策略,并且会为您提供所需的内容。
示例流程
以下摘自:https://web.dev/cross-origin-resource-sharing/#how-does-cors-work
请记住,same-origin 策略告诉浏览器阻止 cross-origin 请求。当您想从不同来源获取 public 资源时,resource-providing 服务器需要告诉浏览器“请求来自的来源可以访问我的资源”。浏览器会记住这一点并允许 cross-origin 资源共享。
第一步:客户端(浏览器)请求
当浏览器发出 cross-origin 请求时,浏览器会添加一个 Origin header 和当前来源(方案、主机和端口)。
第 2 步:服务器响应
在服务器端,当服务器看到此 header 并希望允许访问时,它需要在指定请求来源的响应中添加 Access-Control-Allow-Origin header(或 * 以允许任何来源。)
第三步:浏览器收到响应
当浏览器看到带有适当 Access-Control-Allow-Origin header 的响应时,浏览器允许与客户端站点共享响应数据。
更多链接
这是另一个很好的答案,更详细地说明了正在发生的事情:https://whosebug.com/a/10636765/1137669
我想每个人都知道 cors 是什么以及它的用途。
以一种简单的方式,例如,如果您使用 nodejs 和 express 进行管理,则启用它是这样的
依赖关系:
https://www.npmjs.com/package/cors
app.use (
cors ({
origin: "*",
... more
})
);
而对于本地浏览器请求的问题,只有安装googlechrome这个扩展。
名称:允许 CORS:Access-Control-Allow-Origin
https://chrome.google.com/webstore/detail/allow-cors-access-control/lhobafahddgcelffkeicbaginigeejlf?hl=es
这允许您在本地启用和禁用 cros,问题已解决。
对于 Spring Boot - React js 应用程序,我在控制器上添加了 @CrssOrigin 注释并且它有效:
@CrossOrigin(origins = {"http://localhost:3000"})
@RestController
@RequestMapping("/api")
但注意正确添加 localhost => 'http://localhost:3000',不要在末尾添加“/”=> 'http://localhost:3000/',这是我的问题。
经过很长时间的尝试弄清楚 CORS 的工作原理。我尝试了很多方法在我的 FE 和 BE 代码中修复它。 CORS 错误出现的某些方式,服务器未从客户端接收正文的某些方式以及其他错误...
终于走到了这一步。我希望这可以帮助某人:
BE 代码(NodeJS + Express)
var express = require("express");
const cors = require("cors");
var app = express();
app.use(
cors({
origin: "*",
})
);
app.use(function (req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
next();
});
// your routers and codes
我的FE代码(JS):
fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Connection: 'Keep-Alive',
Authorization: `Bearer test`,
},
body: JSON.stringify(data),
});
您可以使用自定义配置创建一个新的 axios 实例,然后使用这个新配置的实例,
使用 axios-configure.js
创建一个文件,添加这个可共享的导出方法并使用这个 preconfigured import
,而不是像我们传统使用的那样直接导入 axios
,
import axios from 'axios';
import baseUrl from './data-service';
const app = axios.create({
baseURL: baseUrl,
headers: {
'Access-Control-Allow-Origin': '*',
'Content-Type': 'application/json',
},
withCredentials: true
})
export default app;
像这样使用这个导出函数,
import axios from '../YOUR_DIRECTORY/axios-configure';
axios.get();// wont throw cors
不要import axios from axios;
然后使用 axios.get()
它不会抛出 cors
为我们工作,
NOTE this solution will work for them who facing CORS at local environment as local starts at 5000 and backend at 8080, but in production, build gets deployed from java 8080 no CORS in productions (Facing CORS at only local environment)
对于任何使用 cors 包的人更改
const cors = require('cors');
app.use(cors());
至
const cors = require('cors');
app.use(cors({credentials: true, origin: 'http://localhost:5003'}));
将 http://localhost:5003 更改为您的客户端域
我正在 React Web 应用程序中使用 Axios 进行 API 调用。但是,我在 Chrome:
中收到此错误XMLHttpRequest cannot load https://example.restdb.io/rest/mock-data. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8080' is therefore not allowed access.
{
axios
.get("https://example.restdb.io/rest/mock-data", {
headers: {
"x-apikey": "API_KEY",
},
responseType: "json",
})
.then((response) => {
this.setState({ tableData: response.data });
});
}
我也在 Stack Overflow 上阅读了关于同一问题的几个答案,标题为 Access-Control-Allow-Origin
但仍然无法弄清楚如何解决这个问题。我不想在 Chrome 中使用扩展名或使用临时 hack 来解决这个问题。请提出解决上述问题的标准方法。
在尝试了几个答案后,我尝试了这个,
headers: {
'x-apikey': '59a7ad19f5a9fa0808f11931',
'Access-Control-Allow-Origin' : '*',
'Access-Control-Allow-Methods':'GET,PUT,POST,DELETE,PATCH,OPTIONS',
},
现在我得到的错误是,
Request header field Access-Control-Allow-Origin is not allowed by Access-Control-Allow-Headers in preflight response
如果你的后端支持 CORS,你可能需要在你的请求中添加这个 header:
headers: {"Access-Control-Allow-Origin": "*"}
[更新] Access-Control-Allow-Origin 是一个响应 header - 所以为了启用 CORS - 你需要将此 header 添加到服务器的响应中。
但在大多数情况下,更好的解决方案是配置 reverse proxy,以便您的服务器能够将请求从前端重定向到后端,而无需启用 CORS。
您可以在此处找到有关 CORS 机制的文档: https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS
在请求中使用 Access-Control-Allow-Origin header 在这种情况下对您没有帮助,而此 header 只能用于响应...
要使其正常工作,您可能应该将此 header 添加到您的 response.You 中,也可以尝试将 header crossorigin:true
添加到您的请求中。
据我了解,问题是请求从 localhost:3000 发送到 localhost:8080,而浏览器拒绝诸如 CORS 之类的请求。所以解决方案是创建代理
我的解决方案是:
import proxy from 'http-proxy-middleware'
app.use('/api/**', proxy({ target: "http://localhost:8080" }));
在节点js(后端)中,使用cors npm模块
$ npm install cors
然后添加这些行来支持Access-Control-Allow-Origin,
const express = require('express')
const app = express()
app.use(cors())
app.get('/products/:id', cors(), function (req, res, next) {
res.json({msg: 'This is CORS-enabled for a Single Route'});
});
您可以实现相同的效果,无需任何外部模块
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
我遇到了类似的问题,我发现在我的情况下,请求中的 withCredentials: true
正在激活 CORS 检查,而在 header 中发出相同的请求将避免检查:
Reason: expected ‘true’ in CORS header ‘Access-Control-Allow-Credentials’
不使用
withCredentials: true
但设置
'Access-Control-Allow-Credentials':true
在 header 秒。
},
"proxy": "http://localhost:8080",
"devDependencies": {
在package.json
中使用代理$ npm install cors
从 npm 安装 cors 后,将以下代码添加到您的节点应用程序文件中。它解决了我的问题。
var express = require('express')
var cors = require('cors')
var app = express()
app.use(cors())
首先,CORS 绝对是服务器端问题而不是客户端问题,但我非常确定服务器代码在我的情况下是正确的,因为其他应用程序在不同域上使用同一服务器工作。此解决方案在其他答案中有更详细的描述。
当我开始对我的自定义实例使用 axios
时,我的问题就出现了。就我而言,这是一个非常具体的问题,当我们在 axios
实例中使用 baseURL 然后尝试从任何地方进行 GET
或 POST
调用时,axios 添加了一个baseURL 和请求 URL 之间的斜杠 /。这也有道理,但这是隐藏的问题。我的 Laravel 服务器正在重定向以删除导致此问题的尾部斜杠。
通常,飞行前 OPTIONS
请求不喜欢重定向。如果您的服务器使用 301 状态代码进行重定向,则它可能被缓存在不同的级别。所以,一定要检查并避免它。
我有同样的错误。我使用 npm i cors
在后端安装 CORS 解决了这个问题。然后您需要将此添加到您的代码中:
const cors = require('cors');
app.use(cors());
这帮我修好了;现在我可以使用 AJAX post 我的表单,而无需添加任何自定义的 headers.
我在尝试创建 React Axios 实例时遇到了类似的问题。
我使用以下方法解决了它。
const instance = axios.create({
baseURL: "https://jsonplaceholder.typicode.com/",
withCredentials: false,
headers: {
'Access-Control-Allow-Origin' : '*',
'Access-Control-Allow-Methods':'GET,PUT,POST,DELETE,PATCH,OPTIONS',
}
});
试试代理 package.json 添加代码:
"proxy":"https://localhost:port"
并重启 npm enjoy
相同的代码
const instance = axios.create({
baseURL: "/api/list",
});
npm i cors
const app = require('express')()
app.use(cors())
以上代码对我有用。
我将着手解决这个复杂的问题。
什么是来源?
来源本身就是主机名(方案、主机名和端口)i.g。 https://www.google.com
或者可以是本地打开的文件 file://
等。它是某些东西(i.g。网页)的来源。当您打开网络浏览器并转到 https://www.google.com
时,显示给您的网页的来源是 https://www.google.com
。您可以在 Chrome Dev Tools under Security
:
如果您通过文件资源管理器(不通过服务器提供服务)打开本地 HTML 文件,同样适用:
这与 CORS 问题有什么关系?
当您打开浏览器并转到 https://website.com
时,该网站将具有 https://website.com
的来源。该网站将 很可能只会 获取图像、图标、js 文件并对 https://website.com
进行 API 调用,基本上它调用的是与从中提供服务的服务器相同的服务器. 同源调用.
如果您打开网络浏览器并打开本地 HTML 文件,并且在该 html 文件中有 javascript 想要向 google 发出请求例如,您收到以下错误:
same-origin 策略告诉浏览器阻止 cross-origin 请求。在这种情况下,origin null
正在尝试向 https://www.google.com
发出请求(cross-origin 请求)。由于设置了 CORS 策略,浏览器将不允许这样做,并且该策略是不允许 cross-origin 请求。
如果我的页面是从本地主机上的服务器提供的,同样适用:
本地主机服务器示例
如果我们使用以下代码在 localhost:3000 上托管我们自己的本地主机 API 服务器 运行:
const express = require('express')
const app = express()
app.use(express.static('public'))
app.get('/hello', function (req, res) {
// res.header("Access-Control-Allow-Origin", "*");
res.send('Hello World');
})
app.listen(3000, () => {
console.log('alive');
})
然后从文件资源管理器打开一个 HTML 文件(向 localhost:3000 服务器发出请求)目录,将发生以下错误:
由于网页不是从 localhost:3000 上的本地主机服务器提供的,并且通过文件资源管理器,来源与服务器 API 来源不同,因此 cross-origin正在尝试请求。由于 CORS 策略,浏览器正在停止此尝试。
但是如果我们取消注释行:
const express = require('express')
const app = express()
app.use(express.static('public'))
app.get('/hello', function (req, res) {
res.header("Access-Control-Allow-Origin", "*");
res.send('Hello World');
})
app.listen(3000, () => {
console.log('alive');
})
现在再试一次:
它起作用了,因为发送 HTTP 响应的服务器现在包含一个 header 说明 cross-origin 请求可以发生在服务器上,这意味着浏览器会允许它发生,因此没有错误。
如何解决问题(以下之一)
- 从与您发出的请求所在的相同来源(同一主机)提供页面。
- 通过在响应 headers 中明确声明允许服务器接收 cross-origin 请求。
- 如果使用 NGINX 等反向代理,请将 NGINX 配置为发送允许 CORS 的响应 header。
- 不要使用浏览器。例如,使用 cURL,它不像浏览器那样关心 CORS 策略,并且会为您提供所需的内容。
示例流程
以下摘自:https://web.dev/cross-origin-resource-sharing/#how-does-cors-work
请记住,same-origin 策略告诉浏览器阻止 cross-origin 请求。当您想从不同来源获取 public 资源时,resource-providing 服务器需要告诉浏览器“请求来自的来源可以访问我的资源”。浏览器会记住这一点并允许 cross-origin 资源共享。
第一步:客户端(浏览器)请求 当浏览器发出 cross-origin 请求时,浏览器会添加一个 Origin header 和当前来源(方案、主机和端口)。
第 2 步:服务器响应 在服务器端,当服务器看到此 header 并希望允许访问时,它需要在指定请求来源的响应中添加 Access-Control-Allow-Origin header(或 * 以允许任何来源。)
第三步:浏览器收到响应 当浏览器看到带有适当 Access-Control-Allow-Origin header 的响应时,浏览器允许与客户端站点共享响应数据。
更多链接
这是另一个很好的答案,更详细地说明了正在发生的事情:https://whosebug.com/a/10636765/1137669
我想每个人都知道 cors 是什么以及它的用途。 以一种简单的方式,例如,如果您使用 nodejs 和 express 进行管理,则启用它是这样的
依赖关系:
https://www.npmjs.com/package/cors
app.use (
cors ({
origin: "*",
... more
})
);
而对于本地浏览器请求的问题,只有安装googlechrome这个扩展。
名称:允许 CORS:Access-Control-Allow-Origin
https://chrome.google.com/webstore/detail/allow-cors-access-control/lhobafahddgcelffkeicbaginigeejlf?hl=es
这允许您在本地启用和禁用 cros,问题已解决。
对于 Spring Boot - React js 应用程序,我在控制器上添加了 @CrssOrigin 注释并且它有效:
@CrossOrigin(origins = {"http://localhost:3000"})
@RestController
@RequestMapping("/api")
但注意正确添加 localhost => 'http://localhost:3000',不要在末尾添加“/”=> 'http://localhost:3000/',这是我的问题。
经过很长时间的尝试弄清楚 CORS 的工作原理。我尝试了很多方法在我的 FE 和 BE 代码中修复它。 CORS 错误出现的某些方式,服务器未从客户端接收正文的某些方式以及其他错误...
终于走到了这一步。我希望这可以帮助某人:
BE 代码(NodeJS + Express)
var express = require("express");
const cors = require("cors");
var app = express();
app.use(
cors({
origin: "*",
})
);
app.use(function (req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
next();
});
// your routers and codes
我的FE代码(JS):
fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Connection: 'Keep-Alive',
Authorization: `Bearer test`,
},
body: JSON.stringify(data),
});
您可以使用自定义配置创建一个新的 axios 实例,然后使用这个新配置的实例,
使用 axios-configure.js
创建一个文件,添加这个可共享的导出方法并使用这个 preconfigured import
,而不是像我们传统使用的那样直接导入 axios
,
import axios from 'axios';
import baseUrl from './data-service';
const app = axios.create({
baseURL: baseUrl,
headers: {
'Access-Control-Allow-Origin': '*',
'Content-Type': 'application/json',
},
withCredentials: true
})
export default app;
像这样使用这个导出函数,
import axios from '../YOUR_DIRECTORY/axios-configure';
axios.get();// wont throw cors
不要import axios from axios;
然后使用 axios.get()
它不会抛出 cors
为我们工作,
NOTE this solution will work for them who facing CORS at local environment as local starts at 5000 and backend at 8080, but in production, build gets deployed from java 8080 no CORS in productions (Facing CORS at only local environment)
对于任何使用 cors 包的人更改
const cors = require('cors');
app.use(cors());
至
const cors = require('cors');
app.use(cors({credentials: true, origin: 'http://localhost:5003'}));
将 http://localhost:5003 更改为您的客户端域