我正在尝试在启用凭据的情况下在本地主机上的 FastAPI 中启用 CORS。根据docs,在这种情况下我们必须显式设置allow_origins:
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
app = FastAPI()
app.add_middleware(
CORSMiddleware, allow_origins=['http://localhost:8000'],
allow_credentials=True, allow_methods=['*'], allow_headers=['*'])
@app.get('/')
def main():
return Response('OK', status_code=200)
但是,在发出请求时,它确实失败并显示“CORS Missing Allow Origin”:
const response = await fetch('http://localhost:8000/', {credentials: "include"});
客户端是 Firefox,打开了本地文件(file://.../main.html)。
我已经尝试了如何在 FastAPI 中启用 CORS?中的所有解决方案。怎么了?
编辑: 我的问题不是“如何从同一本地网络上的不同计算机/IP 访问 FastAPI 后端?”的重复,因为服务器和客户端位于同一(本地)主机上。尽管如此,我尝试设置建议的 --host 0.0.0.0 并且错误仍然相同。 它也不是
FastAPI is not returned cookies to React frontend 错误,因此应首先为访问本文的未来读者指定该错误。当向服务器(在本例中为 FastAPI 后端)发送 JavaScript 请求时,通过已通过 file:///
URL 加载到浏览器中的本地 HTML 文件,例如,通过将文件拖放到浏览器中或双击文件单击文件 - 浏览器地址栏中的 URL 如下所示:
file:///C:/...index.html
大多数浏览器应用 CORS 并会输出以下错误。如果您使用的是 Chrome(或类似 chrome)浏览器,您会在
CORS error
选项卡/部分的
MissingAllowOriginHeader
列下看到 Status
(跨源资源共享错误:
Network
),表明对 CORS 请求的响应缺少所需的 Access-Control-Allow-Origin
标头,以便确定资源是否可以访问。提交请求后,通过查看控制台可以更清楚地显示错误:可以在
'http://localhost:8000/'
从原点'null'
获取数据 已被 CORS 政策阻止:否标头存在于所请求的资源上。如果回应不透明 满足您的需求,将请求的模式设置为“no-cors”以获取 禁用 CORS 的资源。获取'Access-Control-Allow-Origin'
http://localhost:8000/
网络::ERR_FAILED 200(确定)
如果您使用 FireFox,您会在控制台中看到类似的错误:
跨源请求被阻止:同源策略不允许读取 远程资源位于
http://localhost:8000/
。 (原因:CORS 标头
缺失)。状态代码:200'Access-Control-Allow-Origin'
出现上述错误的原因是您尝试通过通过
file:///
URL 运行的脚本执行跨域请求。在这种情况下,客户端的来源是
null
,但您仅将 'http://localhost:8000'
添加到允许的来源中。因此,快速解决方法是将 null
添加到 origins
列表中,例如 Access-Control-Allow-Origin: null
。在 FastAPI 中,您可以按照下面的示例执行此操作。工作示例
app.py
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
app = FastAPI()
origins = ['null'] # NOT recommended - see details below
app.add_middleware(
CORSMiddleware,
allow_origins=origins,
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
@app.get('/')
def main():
return 'ok'
<!DOCTYPE html>
<html>
<body>
<h1>Send JS request</h1>
<button onclick="getData()">Click me</button>
<script>
function getData() {
fetch('http://localhost:8000/')
.then(resp => resp.json()) // or, resp.text(), etc
.then(data => {
console.log(data);
})
.catch(error => {
console.error(error);
});
}
</script>
</body>
</html>
注意
注意here不应该使用:“返回Access-Control-Allow-Origin: "null"
似乎是安全的,但是 使用非分层方案的任何资源的起源(例如或data:
),沙盒文档定义为file:
。 许多用户代理将授予此类文档访问响应的权限 一个"null"
标头,任何来源都可以 创建一个带有Access-Control-Allow-Origin: "null"
Origin 的敌对文档。"null"
值 对于 ACAO 标头,"null"
因此应该避免。” 正如几个相关问题中所解释的,如
和here所示,人们应该使用本地Web服务器来提供HTML文件,例如上面的index.html
。 FastAPI 也可以使用
HTMLResponse
甚至 Jinja2Templates
为您做到这一点,如 thisanswer、thisanswer 以及 this、this 和 this 中所示。因此,我强烈建议查看这些帖子并通过 FastAPI 提供您的 HTML 文件,这非常简单,而不是将
null
添加到 origins
。关于 CORS 的相关解答也可以在这里和这里找到。