FastAPI 在 header 中不包含 JSON 内容类型,如果尾部斜线在 URL 中

FastAPI doesn't include a JSON content type in the header, if a trailing slash is in the URL

根据我的 URL 中是否有尾部斜杠,FastAPI(使用 uvicorn 服务器)将省略 content type: application/json header。我担心客户可能会无意中在他们的 URL 中添加尾部斜线,然后没有得到 JSON 响应,所以我想知道

a) 这是正确的行为吗?

b) 服务器端如何处理?

这是一个非常简单的 FastAPI 应用程序:

from fastapi import FastAPI
app = FastAPI()

app.get("/alist")
async def alist():
    somelist = [1, 2, 3, 4, 5]
    return somelist

下面是 "correct" 请求的 header 的样子,即没有尾部斜线的请求:

因为尾部有斜杠,所以 content-type: application/json 丢失了,这会使客户感到困惑。

所以根据我上面的问题,这正常吗?我该怎么做才能防止客户期望 JSON 响应但无意中添加了尾部斜线的错误?

a) 这是正确的行为吗?

  • 出现此行为是因为重定向(HTTP 状态代码 307)。
  • 我认为这应该是自动处理的。
  • 所以我认为我们应该在 FastAPI 回购中开一个新问题。

b) 我该如何处理 server-side?

有很多不同的解决方案:

1 - 通过使用一个关键技巧将列表转换为字典(简单的解决方案):

from fastapi import FastAPI
app = FastAPI()

app.get("/alist")
async def alist():
    somelist = [1, 2, 3, 4, 5]
    return {"numbers": somelist}


2 - 通过手动添加 "content-type" header :

使用响应:

from fastapi import FastAPI, Response

app = FastAPI()

app.get("/alist")
async def alist(response: Response):
    # set content-type header to application/json
    response.headers["content-type"] = "application/json"
    somelist = [1, 2, 3, 4, 5]
    return somelist

使用 JSONResponse :

from fastapi import FastAPI
from fastapi.responses import JSONResponse

app = FastAPI()

app.get("/alist")
async def alist():
    somelist = [1, 2, 3, 4, 5]
    # you can add additional headers
    headers = {"X-Cat-Dog": "alone in the world", "Content-Language": "en-US"}
    # json response will enforce "content-type" header to be "application/json"
    return JSONResponse(content=somelist, headers=headers)


您可以在 https://fastapi.tiangolo.com/advanced/response-headers/

阅读有关 FastAPI 响应和 headers 的更多信息