跳至内容

CORS(跨域资源共享)

CORS 或“跨域资源共享” 指的是当在浏览器中运行的前端具有与后端通信的 JavaScript 代码,而该后端与前端位于不同的“来源”的情况。

来源

来源是协议(httphttps)、域(myapp.comlocalhostlocalhost.tiangolo.com)和端口(804438080)的组合。

因此,所有这些都是不同的来源

  • https://127.0.0.1
  • https://127.0.0.1
  • https://127.0.0.1:8080

即使它们都在 localhost 上,它们使用不同的协议或端口,因此,它们是不同的“来源”。

步骤

因此,假设你在浏览器中运行一个前端,该前端位于 https://127.0.0.1:8080,并且其 JavaScript 试图与运行在 https://127.0.0.1 上的后端通信(因为我们没有指定端口,浏览器将假设默认端口 80)。

然后,浏览器将向 :80 后端发送一个 HTTP OPTIONS 请求,如果后端发送了适当的标头来授权来自此不同来源(https://127.0.0.1:8080)的通信,那么 :8080 浏览器将允许前端中的 JavaScript 向 :80 后端发送其请求。

为了实现这一点,:80 后端必须有一个“允许来源”列表。

在这种情况下,该列表必须包含 https://127.0.0.1:8080,才能使 :8080 前端正常工作。

通配符

还可以将列表声明为 "*"(“通配符”),表示允许所有来源。

但这只会允许某些类型的通信,排除所有涉及凭据的通信:Cookie、Authorization 标头(如用于 Bearer 令牌的标头)等。

因此,为了使一切正常工作,最好明确指定允许的来源。

使用 CORSMiddleware

你可以在你的 FastAPI 应用程序中使用 CORSMiddleware 来配置它。

  • 导入 CORSMiddleware
  • 创建一个允许来源列表(作为字符串)。
  • 将其作为“中间件”添加到你的 FastAPI 应用程序中。

你还可以指定你的后端是否允许

  • 凭据(Authorization 标头、Cookie 等)。
  • 特定 HTTP 方法(POSTPUT)或所有方法(使用通配符 "*")。
  • 特定 HTTP 标头或所有标头(使用通配符 "*")。
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware

app = FastAPI()

origins = [
    "https://127.0.0.1.tiangolo.com",
    "https://127.0.0.1.tiangolo.com",
    "https://127.0.0.1",
    "https://127.0.0.1:8080",
]

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


@app.get("/")
async def main():
    return {"message": "Hello World"}

CORSMiddleware 实现使用的默认参数默认情况下是限制性的,因此你需要明确启用特定的来源、方法或标头,以便浏览器才能在跨域上下文中使用它们。

以下参数受支持

  • allow_origins - 应该允许进行跨域请求的来源列表。例如 ['https://example.org', 'https://www.example.org']。你可以使用 ['*'] 允许任何来源。
  • allow_origin_regex - 用于匹配应该允许进行跨域请求的来源的正则表达式字符串。例如 'https://.*\.example\.org'
  • allow_methods - 应该允许用于跨域请求的 HTTP 方法列表。默认为 ['GET']。你可以使用 ['*'] 允许所有标准方法。
  • allow_headers - 用于跨域请求的 HTTP 请求头列表。默认为 []。可以使用 ['*'] 允许所有头。AcceptAccept-LanguageContent-LanguageContent-Type 头部对于 简单的 CORS 请求 始终允许。
  • allow_credentials - 指示是否应支持跨域请求的 cookie。默认为 False。此外,allow_origins 不能设置为 ['*'] 才能允许凭据,必须指定来源。
  • expose_headers - 指示任何应使浏览器可以访问的响应头。默认为 []
  • max_age - 设置浏览器缓存 CORS 响应的最大时间(秒)。默认为 600

中间件会响应两种特定的 HTTP 请求类型...

CORS 预检请求

这些是任何带有 OriginAccess-Control-Request-Method 头部的 OPTIONS 请求。

在这种情况下,中间件将拦截传入请求并使用适当的 CORS 头部进行响应,并使用 200400 响应以供参考。

简单请求

任何带有 Origin 头部的请求。在这种情况下,中间件将像往常一样传递请求,但在响应中包含适当的 CORS 头部。

更多信息

有关 CORS 的更多信息,请查看 Mozilla CORS 文档.

"技术细节"

您还可以使用 from starlette.middleware.cors import CORSMiddleware

FastAPIfastapi.middleware 中提供了几个中间件,仅供开发人员使用。但是,大多数可用的中间件直接来自 Starlette。