18 FastAPI跨域资源共享

跨域资源共享(CORS,Cross-Origin Resource Sharing)是一个浏览器安全机制,允许网页从不同的域、协议或端口请求资源。在默认情况下,浏览器会阻止网页向与其源不同的域发起请求,这对于安全性至关重要。然而,在开发过程中,通常需要允许跨域请求,尤其是在前后端分离的应用场景下。

FastAPI 提供了简单易用的 CORS 配置,允许你轻松启用和配置跨域请求的处理。

1. 什么是 CORS?

CORS 是一种浏览器机制,它通过设置响应头来告知浏览器某个域是否允许访问另一个域的资源。CORS 主要依赖 HTTP 头部,特别是:

  • Access-Control-Allow-Origin:允许访问的来源。
  • Access-Control-Allow-Methods:允许的 HTTP 方法(如 GET、POST、PUT)。
  • Access-Control-Allow-Headers:允许请求中包含的 HTTP 头部。
  • Access-Control-Allow-Credentials:指示是否允许发送 Cookie 信息。

2. FastAPI 中启用和配置 CORS

FastAPI 提供了一个内置的 CORSMiddleware 来帮助我们处理跨域请求。通过这个中间件,我们可以方便地配置哪些来源(Origins)能够访问应用,允许哪些 HTTP 方法,甚至是否允许携带 Cookie。

2.1 安装 CORS 中间件

在 FastAPI 中,CORS 中间件是通过 fastapi.middleware.cors.CORSMiddleware 来实现的。如果你已经安装了 FastAPI 和 Uvicorn,那么 CORS 中间件也是随之安装的。

如果还未安装 FastAPI 和 Uvicorn,可以通过以下命令进行安装:

pip install fastapi uvicorn

2.2 启用 CORS

使用 CORSMiddleware,我们可以快速启用 CORS,并配置允许的跨域访问来源。以下是一个启用 CORS 的基本示例,允许所有来源访问:

from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware

app = FastAPI()

# 配置 CORS
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],  # 允许所有域名的访问
    allow_credentials=True,
    allow_methods=["*"],  # 允许所有 HTTP 方法(GET、POST 等)
    allow_headers=["*"],  # 允许所有请求头
)

@app.get("/items/{item_id}")
async def read_item(item_id: int):
    return {"item_id": item_id}
代码解析:
  • allow_origins=["*"]:允许来自所有域的跨域请求(* 表示所有域名)。
  • allow_credentials=True:允许跨域请求时携带用户凭证(如 Cookies)。
  • allow_methods=["*"]:允许所有 HTTP 方法(如 GETPOSTPUTDELETE 等)。
  • allow_headers=["*"]:允许所有请求头。

2.3 限制特定来源的跨域请求

在生产环境中,通常不会允许所有来源进行跨域访问,而是需要限制特定的来源。例如,只有来自 https://example.comhttps://api.example.com 的请求才允许访问 API。

可以通过设置 allow_origins 来指定允许的来源:

app.add_middleware(
    CORSMiddleware,
    allow_origins=["https://example.com", "https://api.example.com"],  # 仅允许特定来源
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)
代码解析:
  • allow_origins=["https://example.com", "https://api.example.com"]:只允许 https://example.comhttps://api.example.com 域名发起跨域请求。

2.4 配置支持特定 HTTP 方法和头部

你还可以更精细地控制哪些 HTTP 方法和请求头是允许的。例如,限制只允许 GETPOST 请求,并且只允许特定的请求头(如 Authorization):

app.add_middleware(
    CORSMiddleware,
    allow_origins=["https://example.com"],
    allow_credentials=True,
    allow_methods=["GET", "POST"],  # 只允许 GET 和 POST 请求
    allow_headers=["Authorization"],  # 只允许 Authorization 请求头
)
代码解析:
  • allow_methods=["GET", "POST"]:只允许 GETPOST 请求。
  • allow_headers=["Authorization"]:只允许包含 Authorization 请求头的请求。

2.5 允许携带凭证(Cookies)

如果你需要允许跨域请求时携带 Cookie 信息(如用于身份验证的 Cookie),你需要将 allow_credentials 设置为 True,同时配置 allow_origins 为具体的域名,而不是 *

app.add_middleware(
    CORSMiddleware,
    allow_origins=["https://example.com"],  # 只允许指定来源
    allow_credentials=True,  # 允许跨域请求携带 Cookie
    allow_methods=["*"],
    allow_headers=["*"],
)
代码解析:
  • allow_credentials=True:允许跨域请求时发送用户的凭证(如 Cookies)。
  • allow_origins=["https://example.com"]allow_credentials=True 时,allow_origins 不能设置为 *,需要指定具体的域名。

3. CORS 中间件工作原理

CORS 中间件在请求处理过程中通过检查 HTTP 请求的头部来决定是否允许跨域请求。它在以下方面发挥作用:

  1. 请求的预检(Preflight):浏览器在某些情况下会发送一个 OPTIONS 请求(预检请求),用于检查目标服务器是否允许跨域请求。在此请求中,浏览器会发送一些 CORS 相关的头部,如 Access-Control-Request-MethodAccess-Control-Request-Headers。FastAPI 的 CORS 中间件会拦截并处理这个预检请求,返回允许的请求方法和头部。
  2. 设置允许的源:CORS 中间件会根据 Access-Control-Allow-Origin 头部,决定是否允许当前请求的来源跨域访问。它会对请求头中的 Origin 进行匹配,只有当 Origin 符合允许的来源时,才会继续处理请求。
  3. 跨域请求时携带凭证:如果 allow_credentials=True,CORS 中间件会允许跨域请求携带凭证,如 Cookies。此时,Access-Control-Allow-Origin 不能是 *,必须指定具体的源。
  4. 响应修改:CORS 中间件会自动在响应中添加必要的 CORS 头部(如 Access-Control-Allow-OriginAccess-Control-Allow-Methods 等),以告知浏览器是否允许跨域访问。

4. 处理 CORS 错误

当一个跨域请求违反了 CORS 策略时,浏览器会阻止该请求,并在控制台显示 CORS 错误。最常见的错误是:

  • Origin 不匹配:浏览器发送的请求来源与服务器配置的允许的来源不匹配。
  • 请求方法不被允许:浏览器发送的请求方法(如 PUTDELETE)没有被服务器允许。
  • 请求头不被允许:请求中包含了未被服务器允许的自定义请求头。

要解决这些问题,确保你在服务器端配置了正确的 CORSMiddleware 设置,特别是 allow_originsallow_methodsallow_headers

在 FastAPI 中,启用和配置 CORS 是一个简单的过程,可以通过 CORSMiddleware 中间件来完成。你可以根据需求:

  • 允许所有域访问,或者只允许特定来源。
  • 配置允许的 HTTP 方法和请求头。
  • 控制是否允许跨域请求携带凭证。

通过适当地配置 CORS,你可以确保跨域请求能够在不同的前后端之间顺利进行,而不影响应用的安全性。

更多请关注公众号 “学GIS的小宝同学”
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值