CORS 策略:无 'Access-Control-Allow-Origin' / 500(内部服务器错误)问题
CORS policy: No 'Access-Control-Allow-Origin' / 500 (Internal Server Error) Problem
基本上,我正在尝试通过 ID 从 Sequelize 获取用户名。问题是我要么遇到 CORS 问题,要么遇到 500 内部服务器错误,具体取决于响应(状态)
控制器代码
async getUserFromUserId (req, res) {
try {
// const user = await User.findByPk(req.body.id)
const id = req.body.id
const user = await User.findByPk(id)
res.send(user.username)
} catch (err) {
// or res.status(some random number).send() for CORS problem to appear
res.status(500).send({
error: 'an error has occured trying to fetch the users id'
})
}
},
客户代码
this.notifiedUser = (await UserService.getUserFromUserId({id: UserId})).data
不过,我从邮递员那里得到了 Status: 200 OK。
Postman Solution
编辑:
我已经看到其他 Solution 如何解决 cors 问题,但解决方案没有说明为什么我在解决 cors 问题后得到 "undefined" 结果。
如果您的来源来自本地主机,Chrome 通常会阻止来自该来源的任何 CORS 请求。
您可以安装此扩展程序:
或者您可以在 运行 chrome 时禁用安全性(添加标志):
--禁用网络安全
因此,CORS 实际上在这方面确实令人讨厌,但有一种相当简单的方法可以解决此问题。这是一个非常有用的安全功能,尽管有时充其量也令人沮丧。
您的浏览器执行所谓的预检请求,它属于 http 动词 OPTIONS
。您的浏览器调用您想要的任何路由,但它不是您要求它执行的操作,而是首先使用 OPTIONS
调用。您的服务器应该接受客户端可以使用 OPTIONS
方法请求的所有路由,并且您的服务器应该响应以下 header 是一个外部可用的,cross-origin API.
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, ...
(注意,您不应该将 ... 放入,但您可以在此列表中放入任何 HTTP 动词)
如果您需要自己的 header(用于身份验证目的),您需要为客户端 -> 服务器添加此 header。
Access-Control-Allow-Headers: YourHeader, YourHeader2, YourHeader3
你想为服务器添加这个 -> 客户端
Access-Control-Expose-Headers: YourHeader,YourHeader3
请注意,OPTIONS
调用是一个完全独立的调用,您应该像 GET
方法一样处理它。
您现在已经告诉浏览器允许请求什么,以及它可以期望从您的 API 返回什么。如果您不响应 OPTIONS
请求,浏览器会终止请求,从而导致 CORS 错误。
我将猜测一下并假设您可能正在使用 Express,this answer 描述了如何设置 headers。
header在英语中是什么意思?
Access-Control-Allow-Origin
允许客户端从哪里访问此资源(端点)?这可以用通配符匹配部分域,或者只是一个 *
以允许任何地方。
Access-Control-Allow-Methods
此路由允许哪些 HTTP 方法?
Access-Control-Expose-Headers
当我从服务器收到响应时,我(浏览器)应该向 client-side 公开什么?
Access-Control-Allow-Headers
作为允许发送为 headers 的客户端,我是什么?
好的,所以我想出了问题。
在某种程度上,我不必处理任何 cors 问题,因为我相信这不是问题的主要原因。
因此,与其通过 "GET" 访问我的数据库数据并通过以下方式获取数据:
this.data = (Service.function(bodyValue)).data
我做了 "POST" 来获取数据,并通过简单地这样做来访问数据
const response = Service.function({
id: bodyValue
})
this.data = response.data
这无需从数据库中获取 "secured" 信息即可访问数据,而是通过从数据库中获取 Observer 对象信息来访问数据库中的数据。
Observer 对象看起来像 follows,它将用户数据视为对象而不是纯数据。
与数据object相比,其中每个数据{...}都有用户信息。
我不确定我是否使用了正确的词,但这些是我目前理解的范围。
基本上,我正在尝试通过 ID 从 Sequelize 获取用户名。问题是我要么遇到 CORS 问题,要么遇到 500 内部服务器错误,具体取决于响应(状态)
控制器代码
async getUserFromUserId (req, res) {
try {
// const user = await User.findByPk(req.body.id)
const id = req.body.id
const user = await User.findByPk(id)
res.send(user.username)
} catch (err) {
// or res.status(some random number).send() for CORS problem to appear
res.status(500).send({
error: 'an error has occured trying to fetch the users id'
})
}
},
客户代码
this.notifiedUser = (await UserService.getUserFromUserId({id: UserId})).data
不过,我从邮递员那里得到了 Status: 200 OK。 Postman Solution
编辑: 我已经看到其他 Solution 如何解决 cors 问题,但解决方案没有说明为什么我在解决 cors 问题后得到 "undefined" 结果。
如果您的来源来自本地主机,Chrome 通常会阻止来自该来源的任何 CORS 请求。
您可以安装此扩展程序:
或者您可以在 运行 chrome 时禁用安全性(添加标志):
--禁用网络安全
因此,CORS 实际上在这方面确实令人讨厌,但有一种相当简单的方法可以解决此问题。这是一个非常有用的安全功能,尽管有时充其量也令人沮丧。
您的浏览器执行所谓的预检请求,它属于 http 动词 OPTIONS
。您的浏览器调用您想要的任何路由,但它不是您要求它执行的操作,而是首先使用 OPTIONS
调用。您的服务器应该接受客户端可以使用 OPTIONS
方法请求的所有路由,并且您的服务器应该响应以下 header 是一个外部可用的,cross-origin API.
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, ...
(注意,您不应该将 ... 放入,但您可以在此列表中放入任何 HTTP 动词)
如果您需要自己的 header(用于身份验证目的),您需要为客户端 -> 服务器添加此 header。
Access-Control-Allow-Headers: YourHeader, YourHeader2, YourHeader3
你想为服务器添加这个 -> 客户端
Access-Control-Expose-Headers: YourHeader,YourHeader3
请注意,OPTIONS
调用是一个完全独立的调用,您应该像 GET
方法一样处理它。
您现在已经告诉浏览器允许请求什么,以及它可以期望从您的 API 返回什么。如果您不响应 OPTIONS
请求,浏览器会终止请求,从而导致 CORS 错误。
我将猜测一下并假设您可能正在使用 Express,this answer 描述了如何设置 headers。
header在英语中是什么意思?
Access-Control-Allow-Origin
允许客户端从哪里访问此资源(端点)?这可以用通配符匹配部分域,或者只是一个 *
以允许任何地方。
Access-Control-Allow-Methods
此路由允许哪些 HTTP 方法?
Access-Control-Expose-Headers
当我从服务器收到响应时,我(浏览器)应该向 client-side 公开什么?
Access-Control-Allow-Headers
作为允许发送为 headers 的客户端,我是什么?
好的,所以我想出了问题。 在某种程度上,我不必处理任何 cors 问题,因为我相信这不是问题的主要原因。
因此,与其通过 "GET" 访问我的数据库数据并通过以下方式获取数据:
this.data = (Service.function(bodyValue)).data
我做了 "POST" 来获取数据,并通过简单地这样做来访问数据
const response = Service.function({
id: bodyValue
})
this.data = response.data
这无需从数据库中获取 "secured" 信息即可访问数据,而是通过从数据库中获取 Observer 对象信息来访问数据库中的数据。
Observer 对象看起来像 follows,它将用户数据视为对象而不是纯数据。
与数据object相比,其中每个数据{...}都有用户信息。
我不确定我是否使用了正确的词,但这些是我目前理解的范围。