跳到内容

CORS (跨域资源共享)

CORS 或“跨域资源共享” (Cross-Origin Resource Sharing) 指的是当浏览器中运行的前端使用 JavaScript 代码与后端通信时,而后端与前端属于不同的“源 (origin)”的情况。

源是协议 (http, https)、域名 (myapp.com, localhost, localhost.tiangolo.com) 和端口 (80, 443, 8080) 的组合。

因此,以下所有都属于不同的源

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

即使它们都属于 localhost,但它们使用了不同的协议或端口,因此它们属于不同的“源”。

步骤

因此,假设您有一个前端正在您的浏览器中运行,地址为 https://:8080,并且其 JavaScript 正在尝试与运行在 https:// 的后端通信(因为我们没有指定端口,浏览器将假定默认端口 80)。

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

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

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

通配符

也可以将列表声明为 "*"(一个“通配符”)来表示所有都允许。

但这只会允许某些类型的通信,排除所有涉及凭证的通信:Cookie、授权标头(例如与 Bearer Tokens 一起使用的)等。

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

使用 CORSMiddleware

您可以使用 CORSMiddleware 在您的 FastAPI 应用程序中进行配置。

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

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

  • 凭证(授权标头、Cookie 等)。
  • 特定的 HTTP 方法 (POST, PUT) 或使用通配符 "*" 允许所有方法。
  • 特定的 HTTP 标头或使用通配符 "*" 允许所有标头。
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware

app = FastAPI()

origins = [
    "https://.tiangolo.com",
    "https://.tiangolo.com",
    "https://",
    "https://: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 请求标头列表。默认为 []。您可以使用 ['*'] 来允许所有标头。对于简单的 CORS 请求AcceptAccept-LanguageContent-LanguageContent-Type 标头始终是允许的。
  • allow_credentials - 指示是否应支持跨域请求的 Cookie。默认为 False

    如果 allow_credentials 设置为 True,则 allow_originsallow_methodsallow_headers 中的任何一个都不能设置为 ['*']。它们中的所有都必须明确指定

  • 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。