【发布时间】:2021-11-11 01:36:22
【问题描述】:
昨天我问了一个关于我在尝试从 Angular 应用程序向 FastApi 后端发出 POST 请求时遇到的 CORS 错误的问题。经过几次 cmet 后,我决定删除问题以更好地重新检查所有内容。
所以事情有点奇怪。在我的 FastApi 后端,我有以下功能:
@app.post("/hello")
def read_root(request: Request):
print(request)
client_host = request.client.host
return {"client_host": client_host}
@app.post("/pattern-data")
def pattern_input(payload: PatternReconData) -> Dict:
# Does stuff and falls over tragically
return result # this doesn't happen of course
在我的前端,我正在尝试这两种方法:
this.apiService.sendRequest('hello', 'howdy').subscribe(
(response) => {
console.log(response);
},
(error: any) => {
console.log(error);
},
() => {
console.log('done');
}
);
this.apiService.sendRequest('pattern-data', payload).subscribe(
(response: SuccessResponse) => {
console.log(response);
/* do stuff */
},
(error: any) => {
console.log(error);
},
() => {
console.log('done');
},
);
奇怪的是,如果我在 Swagger UI 中测试向 'pattern-data' 发送一些值,由于脚本崩溃,它会返回错误 500。 'hello' 工作正常。
同样,如果我戳.../hello,从前端应用程序开始,我会得到预期的响应:
{client_host: '<some valid ip>'}
但是当尝试将值发送到 .../pattern-data 时会导致 CORS 错误:
Access to XMLHttpRequest at 'http://<my-backend-server>/pattern-data' from origin 'http://localhost:4200' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
但我知道后端已成功接收到负载,因为如果我查看后端日志,我会看到这一点。:
2021-09-16 02:42:38.0130,main,DEBUG,Pattern name received from front-end {data}
所以这表明飞行前检查是成功的,并且允许 Web 应用与后端通信,所以这一切都与 CORS 无关。
这有点令人困惑,并且让我花时间研究 CORS 以及如何处理 CORS 错误让我非常伤心,而实际上我的问题与它无关。
我不明白为什么我没有收到错误 500,而是收到了 CORS 错误。这是因为后端根本无法发送响应,而浏览器 (Chrome) 将无响应解释为没有必要的标头并显示 CORS 错误?
这是来自 Chrome 开发工具标题部分。戳/hello:
Request URL: http://<my-backend-server>/hello
Request Method: POST
Status Code: 200 OK
Remote Address: <some valid ip>
Referrer Policy: strict-origin-when-cross-origin
access-control-allow-credentials: true
access-control-allow-origin: http://localhost:4200
content-length: 31
content-type: application/json
date: Thu, 16 Sep 2021 02:43:09 GMT
server: uvicorn
vary: Origin
发送数据到/pattern-data:
Request URL: http://<my-backend-server>/pattern-data
Referrer Policy: strict-origin-when-cross-origin
content-length: 21
content-type: text/plain; charset=utf-8
date: Thu, 16 Sep 2021 02:43:09 GMT
server: uvicorn
【问题讨论】:
-
好吧,错误说明了一切,服务响应中缺少 cors 标头。在 swagger UI 中,它可能正在工作,因为这是由 swagger 自己提供的(因此没有交叉起源)。当您从本地主机请求时,服务器不会发送任何 cors 标头,因此您的浏览器拒绝访问响应中的数据。
-
@derpirscher 很公平,但据我了解,CORS 是一种飞行前检查,在允许前端与后端通信之前进行.但我所拥有的是后端成功接收数据,这对我来说意味着握手并且允许 POST 方法通过。
-
CORS 不会指导任何有关 POST 方法的操作 - 它仅与是否允许客户端读取响应有关(即,只要 OPTIONS 调用(预检)是OK-ed - 在没有运行发生 500 错误的视图代码的情况下发生这种情况)。
-
我不确定你认为 CORS 的目标是什么 - 它会验证浏览器发送的
Origin标头是否在接受的来源中,它会告诉请求浏览器它允许读取服务的响应。如果您发出明确的 HTTP 请求,无论任何 CORS 限制如何(例如使用curl或类似),它都会通过。它可以保护您免受代表用户浏览器向资源发出请求的 3rd 方站点(Origin:与您的预期不同)。 -
发生错误时,response 上的预期 CORS 标头不存在(由于发生异常,中间件不会运行)。由于预期的 CORS 标头不存在,浏览器会返回 CORS 错误,即使底层错误是 500 错误 - 由于请求没有所需的 CORS 标头,浏览器无法报告除 CORS 错误之外的任何内容(因为它会泄露它未被允许提供的信息)。
标签: angular cors backend fastapi