如何在 FastAPI 中为通过 file:/// URL 加载的本地 HTML 文件启用 CORS?

问题描述 投票:0回答:1

我正在尝试在启用凭据的情况下在本地主机上的 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

的重复,因为它建议以与官方文档相同的方式设置CORS源,这并不像我上面描述的那样工作。

javascript python cors fastapi local
1个回答
0
投票
CORS

错误,因此应首先为访问本文的未来读者指定该错误。当向服务器(在本例中为 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 政策阻止:否
'Access-Control-Allow-Origin'
标头存在于所请求的资源上。如果回应不透明 满足您的需求,将请求的模式设置为“no-cors”以获取 禁用 CORS 的资源。
获取

http://localhost:8000/

网络::ERR_FAILED 200(确定)


如果您使用 FireFox,您会在控制台中看到类似的错误:

跨源请求被阻止:同源策略不允许读取 远程资源位于
http://localhost:8000/

。 (原因:CORS 标头

'Access-Control-Allow-Origin'
缺失)。
状态代码:200

出现上述错误的原因是您尝试通过通过
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'

index.html

<!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>

注意

但是,

不建议

这样做,因为它不安全。如 MDN 文档中所述:

注意

null

不应该
使用:“返回Access-Control-Allow-Origin: "null"似乎是安全的,但是 使用非分层方案的任何资源的起源(例如
data:
file:
),沙盒文档定义为
"null"
。 许多用户代理将授予此类文档访问响应的权限 一个
Access-Control-Allow-Origin: "null"
标头,任何来源都可以 创建一个带有
"null"
Origin 的敌对文档。
"null"
值 对于 ACAO 标头,
因此应该避免
。”

正如几个相关问题中所解释的,如
here

here所示,人们应该使用本地Web服务器来提供HTML文件,例如上面的index.html。 FastAPI 也可以使用

HTMLResponse
甚至
Jinja2Templates
为您做到这一点,如
thisanswer
thisanswer 以及 thisthisthis 中所示。因此,我强烈建议查看这些帖子并通过 FastAPI 提供您的 HTML 文件,这非常简单,而不是将 null 添加到
origins
关于 CORS 的相关解答也可以在

这里

这里找到。

© www.soinside.com 2019 - 2024. All rights reserved.