CORS(跨域资源共享)¶
CORS(跨域资源共享)是指前后端不同源时,浏览器中运行的前端 JavaScript 代码与后端通信的情况。
源¶
源是协议(http
、https
)、域(myapp.com
、localhost
、localhost.tiangolo.com
)及端口(80
、443
、8080
)的组合。
下面是几个不同的源:
http://localhost
https://localhost
http://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。