【问题标题】:CORS error when using pyyaml with FastAPI将 pyyaml 与 FastAPI 一起使用时出现 CORS 错误
【发布时间】:2020-02-25 14:42:45
【问题描述】:

我正在尝试使用 react 前端和 fastapi 后端创建一个简单的 Web 应用程序。 Web 应用程序的一个功能是发送在前端收集并在后端处理的文件。我在后端有一个端点,如下所示:

@app.post("/upload_file/")
async def create_upload_file(file: UploadFile = File(...)):
    for line in file.file.readlines():
        print(line)
    file.file.close()
    return {"filename": file.filename}

我已确认此代码有效。我可以从前端发送一个文件,观察后端终端上打印出来的行,然后前端会收到一个带有 200 状态码和文件名的 http 响应。

当我尝试使用 pyyaml 库处理入站 yaml 文件时,问题就出现了。下面是一个不起作用的代码 sn-p:

@app.post("/upload_file/")
async def create_upload_file(file: UploadFile = File(...)):
    yaml_data = yaml.load(file, Loader=yaml.FullLoader)
    return yaml_data

我得到错误:

Access to XMLHttpRequest at 'http://127.0.0.1:8000/upload_file/' (redirected from 'http://127.0.0.1:8000/upload_file') from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

所以这似乎是一个 CORS 问题...我目前的 FastAPI 的 CORS 政策如下所示:

origins = [
    "http://localhost",
    "http://localhost:3000",
    "http://127.0.0.1:8000",
]

app.add_middleware(
    CORSMiddleware,
    allow_origins=origins,
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

我是否必须在我的 CORS 策略中添加一些内容以允许它使用 pyyaml?我不认为会是这种情况,因为处理仍然应该在同一个端点上完成(注意端点在同一个地方),但是 CORS 显然不喜欢使用 yaml.load() 函数。任何关于能够在我的后端加载 yaml 文件的建议将不胜感激。

根据 Rishabh Batra 的请求,我在此处添加了 OPTIONS 标头:

【问题讨论】:

  • 您能否在浏览器控制台中检查浏览器发送到 API 的 OPTIONS 调用标头并添加这些标头?

标签: python cors pyyaml fastapi


【解决方案1】:

解决了。原来starlette 是一个由FastAPI 构建的库,UploadFile 对象与python 文件对象不同。如果你想让它表现得像一个 python 文件对象,你必须做file.file。因此,对于上述失败的 sn-p,正确的方法是:

@app.post("/upload_file/")
async def create_upload_file(file: UploadFile = File(...)):
    yaml_data = yaml.load(file.file, Loader=yaml.FullLoader)
    return yaml_data

CORS 政策是正确的,不知道为什么会引发 CORS 错误

【讨论】:

    【解决方案2】:

    在您可以使用的不同端口上运行的后端代码 * 或定义在您的应用上使用的所有端口

    origins = [
        "http://localhost:*",
        "http://localhost:3000",
        "http://127.0.0.1:8000",
    ]
    

    【讨论】:

    • 不,添加通配符似乎没有帮助,这会产生同样的错误
    • 您的应用程序在不同的端口上运行检查
    • 我的前端在localhost:3000 上运行,我的后端在127.0.0.1:8000 上运行,两者都包含在origins 中。您还会注意到,当您不在同一端点上调用 yaml.load() 时,代码会运行,因此它可能与端点无关,可能与调用 yaml.load() 时的某些重定向有关
    • 还有错误和代码头显示它 307 重定向,因此路径错误,检查您的代码。打开控制台网络并查看请求的去向
    • 如果路径错误,为什么我不在后端运行 yaml.load() 行时它会起作用?
    猜你喜欢
    • 1970-01-01
    • 2020-10-09
    • 2021-07-26
    • 2014-08-23
    • 2021-06-25
    • 2018-06-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多