CORS(跨域资源共享)¶
CORS(跨域资源共享)是指前后端不同源时,浏览器中运行的前端 JavaScript 代码与后端通信的情况。
源¶
源是协议(http、https)、域(myapp.com、localhost、localhost.tiangolo.com)及端口(80、443、8080)的组合。
下面是几个不同的源:
http://localhosthttps://localhosthttp://localhost:8080
即使都在 localhost 中,但因为使用了不同协议或端口,所以它们是不同的源。
步骤¶
假设前端在 http://localhost:8080,并且它的 JavaScript 要与在 http://localhost 的后端通信(因为没有指定端口,浏览器使用默认端口 80)。
然后,浏览器向后端发送 HTTP OPTIONS 请求,如果后端发送的请求头授权许可与不同源(http://localhost:8080)通信,浏览器就允许前端的 JavaScript 向后端发送请求。
为此,后端必须定义许可源列表。
只有源列表中包含了 http://localhost:8080,前端才能正常工作。
通配符¶
使用 "*"(通配符)声明源列表,表示许可所有源。
但这只能允许某些类型的通信,不包括所有涉及凭据的通信:Cookies 及使用 Bearer + Token 的授权请求头等。
为了一切都能正常运行,最好显式指定许可源。
使用 CORSMiddleware¶
FastAPI 应用使用 CORSMiddleware 配置源列表。
- 导入
CORSMiddleware - 创建(由字符串组成的)许可源列表
- 把源列表作为中间件添加到 FastAPI 应用
还可以指定后端是否允许:
- 凭证(授权请求头,Cookies 等)
- 指定 HTTP 方法(
POST、PUT),或使用通配符"*"允许所有方法 - 指定 HTTP 请求头,或使用通配符
"*"允许所有请求头
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
app = FastAPI()
origins = [
"http://localhost.tiangolo.com",
"https://localhost.tiangolo.com",
"http://localhost",
"http://localhost: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 的默认参数比较保守,所以要显式启用指定的源、方法和请求头,以供浏览器在跨域上下文中使用。
CORS 中间件支持以下参数:
allow_origins- 允许跨域请求的源列表。例如['https://example.org', 'https://www.example.org']。['*']允许所有源allow_origin_regex- 正则表达式字符串,允许与之匹配的源跨域请求。例如'https://.*\.example\.org'allow_methods- 允许跨域请求的 HTTP 方法列表。默认为['GET']。['*']允许所有标准方法allow_headers- 允许跨域请求的 HTTP 请求头列表。默认为[]。['*']允许所有请求头。Accept、Accept-Language、Content-Language及Content-Type请求头总是允许 CORS 请求allow_credentials- 允许跨域请求支持 cookies,默认是False。另外,allow_origins不能设定为['*'],必须指定源expose_headers- 指定允许浏览器访问的响应头。默认为[]max_age- 设定浏览器缓存 CORS 响应的最长时间,单位是秒。默认为600
中间件响应两种特定类型的 HTTP 请求……
CORS 预检请求¶
对于任意带有 Origin 和 Access-Control-Request-Method 请求头的 OPTIONS 请求。
中间件会拦截传入的请求并进行响应,出于提供信息的目的返回使用适当的 CORS 请求头的 200 或 400 响应。
简单请求¶
对于任何带有 Origin 请求头的请求。中间件正常传递请求,但在响应中包含适当的 CORS 请求头。
更多信息¶
更多 CORS 说明详见 Mozilla CORS 文档。
技术细节
您也可以直接使用 from starlette.middleware.cors import CORSMiddleware。
为了方便调用,FastAPI 在 fastapi.middleware 中为开发者提供了几个中间件,但大多数中间件都直接继承自 Starlette。