FastAPI?提供了一些中間件來增強(qiáng)它的功能,類似于 Spring 的切面編程,中間件可以在請(qǐng)求處理前或處理后執(zhí)行一些操作,例如記錄日志、添加請(qǐng)求頭、鑒權(quán)等,跨域也是 FastAPI?中間件的一部分。
目錄
1 中間件
1.1?創(chuàng)建中間件
1.2 使用中間件?
2 跨域
2.1 跨域詳解
2.2 使用 CORSMiddleware 實(shí)現(xiàn)跨域
???源碼地址:
FastAPI_Study_Yinyu: FastAPI學(xué)習(xí)路徑,CSDN專欄:http://t.csdn.cn/JRtrk
1 中間件
你可以通過向 FastAPI 應(yīng)用添加中間件來實(shí)現(xiàn)類似切面編程的的效果。
簡(jiǎn)單來說,中間件也就是一個(gè)函數(shù),它可以在每個(gè)請(qǐng)求處理之前及請(qǐng)求處理之后工作:
- 他接收來自客戶端的每一個(gè)請(qǐng)求:
- 可對(duì)每個(gè)請(qǐng)求執(zhí)行任何需要的代碼
- 可將請(qǐng)求傳遞給后臺(tái)的其他部分 (通過某種路徑操作)
- 可獲取應(yīng)用程序生產(chǎn)的響應(yīng) (通過某種路徑操作)
- 可針對(duì)某響應(yīng)做些什么或者執(zhí)行任何需要的代碼
- 然后它返回這個(gè)響應(yīng)
1.1?創(chuàng)建中間件
首先我們使用裝飾器 @app.middleware("http") 來創(chuàng)建一個(gè)簡(jiǎn)單的中間件:
中間件參數(shù)接收如下參數(shù):
- request:具體請(qǐng)求
-
call_next:函數(shù),它將接收 request 作為參數(shù)
- 這個(gè)函數(shù)將 request 傳遞給相應(yīng)的路徑操作
- 然后它將返回由相應(yīng)的路徑操作生成的 response
- 然后你可以在返回 response 前,進(jìn)一步修改它
import time
from fastapi import FastAPI, Request
app = FastAPI()
@app.middleware("http")
async def add_process_time_header(request: Request, call_next):
#請(qǐng)求處理前
response = await call_next(request)
#請(qǐng)求處理后
return response
你可以在請(qǐng)求處理前和請(qǐng)求處理后添加相應(yīng)的邏輯代碼~
1.2 使用中間件?
接下來我們使用上述的模板,使用中間件來完成一個(gè)需求(添加自定義請(qǐng)求頭 X-Process-Time ,包含以秒為單位的接收請(qǐng)求和生成響應(yīng)的時(shí)間)
import time
from fastapi import FastAPI, Request
app = FastAPI()
#中間件,相當(dāng)于切面編程
@app.middleware("http")
async def add_process_time_header(request: Request, call_next):
start_time = time.time()
time.sleep(1)
response = await call_next(request)
process_time = time.time() - start_time
response.headers["X-Process-Time-Yinyu"] = str(process_time)
return response
#請(qǐng)求示例
@app.get("/test/")
async def read_item():
return "OK"
if __name__ == '__main__':
import uvicorn
uvicorn.run(app, host="127.0.0.1", port=8000)
然后我們啟動(dòng)這個(gè)應(yīng)用然后進(jìn)行請(qǐng)求 ??,這說明中間件起到作用了。
?但是如果你想讓瀏覽器中的客戶端看到你的自定義請(qǐng)求頭,你需要把它們加到 CORS 配置 (CORS (Cross-Origin Resource Sharing)) 的 expose_headers 參數(shù)中。
2 跨域
假如是前后端分離的項(xiàng)目(比如前端 Vue,后端 Fastapi),那跨域就繞不過去了。
2.1 跨域詳解
首先跨域是指瀏覽器中運(yùn)行的前端擁有與后端通信的 JavaScript 代碼,而后端處于與前端不同的「源」的情況。
???源
源是指協(xié)議(http,https)、域(myapp.com,localhost,localhost.tiangolo.com)以及端口(80、443、8080)的組合。
這些都是不同的源:
- http://localhost
- https://localhost
- http://localhost:8080
即使它們都在 localhost 中,但是它們使用不同的協(xié)議或者端口,所以它們都是不同的「源」。
???跨域必要性
假設(shè)你的瀏覽器中有一個(gè)前端運(yùn)行在 http://localhost:8080,并且它的 JavaScript 正在嘗試與運(yùn)行在 http://localhost 的后端通信(如果我們沒有指定端口,瀏覽器會(huì)采用默認(rèn)的端口 80)。
然后,瀏覽器會(huì)向后端發(fā)送一個(gè) HTTP OPTIONS 請(qǐng)求,如果后端發(fā)送適當(dāng)?shù)?headers 來授權(quán)來自這個(gè)不同源(http://localhost:8080)的通信,瀏覽器將允許前端的 JavaScript 向后端發(fā)送請(qǐng)求。
因此后端需要有一個(gè)「允許的源」列表。 在這種情況下,包含 http://localhost:8080,前端才能正常工作。
也可以使用 "*"?聲明這個(gè)列表,表示全部都是允許的,但也不會(huì)影響授權(quán)認(rèn)證方面的處理。
2.2 使用 CORSMiddleware 實(shí)現(xiàn)跨域
主要步驟如下:
- 導(dǎo)入 CORSMiddleware。
- 創(chuàng)建一個(gè)允許的源列表(由字符串組成)。
- 將其作為「中間件」添加到你的 FastAPI 應(yīng)用中。
還可以做如下指定:
- 憑證(授權(quán) headers,Cookies 等)。
- 特定的 HTTP 方法(POST,PUT)或者使用通配符 "*" 允許所有方法。
- 特定的 HTTP headers 或者使用通配符 "*" 允許所有 headers。
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"}
默認(rèn)情況下,CORSMiddleware 默認(rèn)實(shí)現(xiàn)的參數(shù)較為保守,因此需要顯式地啟用特定的源、方法或者 headers,以便瀏覽器能夠在跨域上下文中使用它們。文章來源:http://www.zghlxwxcb.cn/news/detail-487526.html
支持以下參數(shù):文章來源地址http://www.zghlxwxcb.cn/news/detail-487526.html
- allow_origins :允許跨域請(qǐng)求的源列表。例如 ['https://example.org', 'https://www.example.org'],你可以使用 ['*'] 允許任何源。
- allow_origin_regex :一個(gè)正則表達(dá)式字符串,匹配的源允許跨域請(qǐng)求。例如 'https://.*\.example\.org'。
- allow_methods :允許跨域請(qǐng)求的 HTTP 方法列表,默認(rèn)為 ['GET'],你可以使用 ['*'] 來允許所有標(biāo)準(zhǔn)方法。
- allow_headers:允許跨域請(qǐng)求的 HTTP 請(qǐng)求頭列表。默認(rèn)為 [](空)。你可以使用 ['*'] 允許所有的請(qǐng)求頭,Accept、Accept-Language、Content-Language 以及 Content-Type 請(qǐng)求頭總是允許 CORS 請(qǐng)求。
- allow_credentials:指示跨域請(qǐng)求支持 cookies,默認(rèn)是 False。另外,允許憑證時(shí) allow_origins 不能設(shè)定為 ['*'],必須指定源。
- expose_headers:指示可以被瀏覽器訪問的響應(yīng)頭。默認(rèn)為 []。
- max_age:設(shè)定瀏覽器緩存 CORS 響應(yīng)的最長(zhǎng)時(shí)間,單位是秒。默認(rèn)為 600。
到了這里,關(guān)于【Python開發(fā)】FastAPI 09:middleware 中間件及跨域的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!