欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Python web框架fastapi中間件的使用及CORS跨域問(wèn)題

 更新時(shí)間:2024年03月08日 11:30:51   作者:景天科技苑  
fastapi "中間件"是一個(gè)函數(shù),它在每個(gè)請(qǐng)求被特定的路徑操作處理之前,以及在每個(gè)響應(yīng)之后工作,它接收你的應(yīng)用程序的每一個(gè)請(qǐng)求,下面通過(guò)本文給大家介紹Python web框架fastapi中間件的使用及CORS跨域問(wèn)題,感興趣的朋友一起看看吧

fastapi中間件與CORS

1、中間件

你可以向 FastAPI 應(yīng)用添加中間件。

fastapi "中間件"是一個(gè)函數(shù),它在每個(gè)請(qǐng)求被特定的路徑操作處理之前,以及在每個(gè)響應(yīng)之后工作.
它接收你的應(yīng)用程序的每一個(gè)請(qǐng)求.
然后它可以對(duì)這個(gè)請(qǐng)求做一些事情或者執(zhí)行任何需要的代碼.
然后它將請(qǐng)求傳遞給應(yīng)用程序的其他部分 (通過(guò)某種路徑操作).
然后它獲取應(yīng)用程序生產(chǎn)的響應(yīng) (通過(guò)某種路徑操作).
它可以對(duì)該響應(yīng)做些什么或者執(zhí)行任何需要的代碼.
然后它返回這個(gè) 響應(yīng).

請(qǐng)求與響應(yīng)中間件,并不是需要每次都要寫
根據(jù)業(yè)務(wù)需求
例如:如果向做個(gè)請(qǐng)求攔截中間件,攔截那些非法請(qǐng)求的ip,只需要在請(qǐng)求中間件中做限制即可,無(wú)需讓該用戶的請(qǐng)求到達(dá)業(yè)務(wù)邏輯層
如果想做響應(yīng)給每個(gè)用戶的頁(yè)面添加個(gè)作者信息的響應(yīng)頭,不需要在業(yè)務(wù)代碼每個(gè)邏輯都做,只需要在響應(yīng)中間件處做個(gè)響應(yīng)中間件即可
當(dāng)然,也有兩個(gè)中間件都用到的,例如測(cè)試請(qǐng)求的響應(yīng)時(shí)間

1.創(chuàng)建中間件方法

要?jiǎng)?chuàng)建中間件你可以在函數(shù)的頂部使用裝飾器 @app.middleware(“http”).

中間件參數(shù)接收如下參數(shù):

  • request.
  • 一個(gè)函數(shù)call_next,它將接收request,作為參數(shù),然后執(zhí)行下一個(gè)中間件.
    • 這個(gè)函數(shù)將 request 傳遞給相應(yīng)的 路徑操作.
    • 然后它將返回由相應(yīng)的路徑操作生成的 response.
  • 然后你可以在返回 response 前進(jìn)一步修改它.

請(qǐng)求中間件函數(shù)在最下面的最先執(zhí)行

案例:

import time
from fastapi import FastAPI  # FastAPI 是一個(gè)為你的 API 提供了所有功能的 Python 類。
import uvicorn
from fastapi import Request
#創(chuàng)建應(yīng)用程序,app是應(yīng)用程序名
app = FastAPI()  # 這個(gè)實(shí)例將是創(chuàng)建你所有 API 的主要交互對(duì)象。這個(gè) app 同樣在如下命令中被 uvicorn 所引用
#定義中間件m2
@app.middleware('http') #全局中間件
async def m2(request:Request,call_next):
    #請(qǐng)求代碼塊
    print("m2 request")
    response = await call_next(request)
    #響應(yīng)代碼塊
    print("m2 response")
    # 每個(gè)中間件的response,都是訪問(wèn)的邏輯函數(shù)的響應(yīng)體
    return response
#定義中間件m1
@app.middleware('http') #全局中間件
async def m1(request:Request,call_next):
    #請(qǐng)求代碼塊
    print("m1 request")
    response = await call_next(request)
    #響應(yīng)代碼塊
    print("m1 response")
    #每個(gè)中間件的response,都是訪問(wèn)的邏輯函數(shù)的響應(yīng)體
    return response
@app.get("/user")
def get_user():
    time.sleep(3)
    print("get_user函數(shù)執(zhí)行")
    return {
        "user": "current user"
    }
@app.get("/item/{item_id}")
def get_item(item_id: int):
    time.sleep(2)
    print("get_item函數(shù)執(zhí)行")
    return {
        "item_id": item_id
    }
if __name__ == '__main__':
    #注意,run的第一個(gè)參數(shù) 必須是文件名:應(yīng)用程序名
    uvicorn.run("main:app", port=8083,  reload=True,workers=1)

我們測(cè)試接口/user,看下請(qǐng)求與響應(yīng)順序

請(qǐng)求先走m1中間件,再走m2中間件。然后是邏輯函數(shù)響應(yīng),然后走走m2中間件響應(yīng),最后走m1中間件響應(yīng)

2.中間件里面添加響應(yīng)頭

#定義中間件m2
@app.middleware('http') #全局中間件
async def m2(request:Request,call_next):
    #請(qǐng)求代碼塊
    print("m2 request")
    response = await call_next(request)
    #響應(yīng)代碼塊
    print("m2 response")
    #添加響應(yīng)頭
    response.headers['author'] = 'jingtian'
    # 每個(gè)中間件的response,都是訪問(wèn)的邏輯函數(shù)的響應(yīng)體
    return response

測(cè)試,可以看到所有接口,都添加了個(gè)響應(yīng)頭

3.在請(qǐng)求處,設(shè)置攔截等等

if request.client.host in ['127.0.0.1']:
    return  Response(content='visit forbidden',status_code=403)

訪問(wèn)接口

也可以針對(duì)某個(gè)接口請(qǐng)求做限制

if request.url.path in ["/user"]:
    return Response(content="visit forbidden",status_code=403)

訪問(wèn)/user接口被拒絕

訪問(wèn)其他接口正常

4.測(cè)試接口響應(yīng)時(shí)間

可以在最后一個(gè)中間件做

#定義中間件m1
@app.middleware('http') #全局中間件
async def m1(request:Request,call_next):
    #請(qǐng)求代碼塊
    print("m1 request")
    # if request.client.host in ['127.0.0.1']:
    #     return  Response(content='visit forbidden',status_code=403)
    start = time.time()
    if request.url.path in ["/user"]:
        return Response(content="visit forbidden",status_code=403)
    response = await call_next(request)
    #響應(yīng)代碼塊
    print("m1 response")
    #測(cè)試訪問(wèn)結(jié)束時(shí)間
    end = time.time()
    response.headers["ProcessTimer"] = str(end - start)
    #每個(gè)中間件的response,都是訪問(wèn)的邏輯函數(shù)的響應(yīng)體
    return response
我們針對(duì)每個(gè)接口做了響應(yīng)時(shí)間阻塞
@app.get("/user")
def get_user():
    time.sleep(3)
    print("get_user函數(shù)執(zhí)行")
    return {
        "user": "current user"
    }
@app.get("/item/{item_id}")
def get_item(item_id: int):
    time.sleep(2)
    print("get_item函數(shù)執(zhí)行")
    return {
        "item_id": item_id
    }

測(cè)試,/item接口響應(yīng)時(shí)間為2秒多

/user接口響應(yīng)時(shí)間,響應(yīng)3秒多

2、CORS

1.同源策略帶來(lái)的跨域問(wèn)題

在前后端分離的項(xiàng)目中,前端和后端如果部署在同一個(gè)服務(wù)器,那么運(yùn)行端口肯定不一樣
當(dāng)前端發(fā)起請(qǐng)求到后端,這個(gè)時(shí)候發(fā)送的首先是 option 請(qǐng)求,而不是真正的請(qǐng)求
后端拿到 option 請(qǐng)求后先判斷有沒有資格(權(quán)限),如果沒有就會(huì)報(bào)錯(cuò);如果有,則會(huì)繼續(xù)請(qǐng)求你真正發(fā)起的請(qǐng)求
一句話總結(jié):在瀏覽器中運(yùn)行的前端編寫了和服務(wù)端通信的 JavaScript 代碼,而服務(wù)端與前端處于不同“源”的情況
協(xié)議相同+域名相同+端口號(hào)相同,瀏覽器才認(rèn)為是同一個(gè)網(wǎng)站,才不會(huì)受到同源策略的影響,才可以正常的發(fā)送Ajax請(qǐng)求

2.跨域的解決方法

因?yàn)闉g覽器同源策略,也正是有了跨域限制,才使我們能安全的上網(wǎng)
但是在實(shí)際開發(fā)中,有時(shí)候需要突破這樣的限制,所以就誕生了 CORS

3.CORS

Cross-Origin Resource Sharing 跨域資源共享
是一種基于 HTTP Headers 的機(jī)制,該機(jī)制通過(guò)允許服務(wù)器標(biāo)示除了它自己以外的其它origin(域名,協(xié)議和端口),這樣瀏覽器可以訪問(wèn)加載這些跨域資源
CORS 還通過(guò)一種機(jī)制來(lái)檢查服務(wù)器是否會(huì)允許要發(fā)送的真實(shí)請(qǐng)求,該機(jī)制通過(guò)瀏覽器發(fā)起一個(gè)到服務(wù)器托管的跨源資源的"預(yù)檢"請(qǐng)求
在預(yù)檢中,瀏覽器發(fā)送的 Headers 中標(biāo)示有 HTTP 方法和真實(shí)請(qǐng)求中會(huì)用到的頭

案例:

后端代碼:

from fastapi import FastAPI  # FastAPI 是一個(gè)為你的 API 提供了所有功能的 Python 類。
import uvicorn
#創(chuàng)建應(yīng)用程序,app是應(yīng)用程序名
app = FastAPI()  # 這個(gè)實(shí)例將是創(chuàng)建你所有 API 的主要交互對(duì)象。這個(gè) app 同樣在如下命令中被 uvicorn 所引用
@app.get("/user")
def get_user():
    print("user:jingtian", )
    return {
        "user": "jingtian"
    }
if __name__ == '__main__':
    #注意,run的第一個(gè)參數(shù) 必須是文件名:應(yīng)用程序名
    uvicorn.run("CORS:app", port=8080,  reload=True)

創(chuàng)建個(gè)前端頁(yè)面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js"></script>
</head>
<body>
<p>click</p>
<script>
    $("p").click(function () {
        $.ajax({
            url: "http://127.0.0.1:8080/user",
            success: function (res) {
                console.log(res)
                console.log(res.user)
                $("p").html("hello " + res.user)
            },
        })
    })
</script>
</body>
</html>

我們?cè)诒镜赜脼g覽器將html文件打開,可以看到協(xié)議,域名都與服務(wù)端不同

此時(shí),我們點(diǎn)擊click,可以看到出現(xiàn)了同源跨域攔截

后端改造,實(shí)現(xiàn)CORS,資源跨域共享
添加個(gè)響應(yīng)中間件

1.方式一

@app.middleware("http")
async def CORSMiddleware(request: Request, call_next):
    response = await call_next(request)
    response.headers["Access-Control-Allow-Origin"] = "*"
    return response

此時(shí)再在頁(yè)面點(diǎn)擊click,拿到數(shù)據(jù)

看下響應(yīng)頭,就有了我們添加的響應(yīng)頭 Access-Control-Allow-Origin

如果只允許部分網(wǎng)站來(lái)訪問(wèn),那么就不要用*,使用允許訪問(wèn)的ip(域名)和端口

2.方式二

使用fastapi自帶的中間件

from fastapi.middleware.cors import CORSMiddleware
#方式二
origins = [
    "http://localhost:63342"
]
app.add_middleware(
    CORSMiddleware,
    allow_origins="*",  # *:代表所有客戶端
    allow_credentials=True,
    allow_methods=["GET", "POST"],
    allow_headers=["*"],
)

默認(rèn)情況下,CORSMiddleware 默認(rèn)實(shí)現(xiàn)的參數(shù)較為保守,因此需要顯式地啟用特定的源、方法或者 headers,以便瀏覽器能夠在跨域上下文中使用它們。

支持以下參數(shù):

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’],你可以使用 [‘‘] 來(lái)允許所有標(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:指示可以被瀏覽器訪問(wèn)的響應(yīng)頭。默認(rèn)為 []。
max_age:設(shè)定瀏覽器緩存 CORS 響應(yīng)的最長(zhǎng)時(shí)間,單位是秒。默認(rèn)為 600。

點(diǎn)擊,也能實(shí)現(xiàn)跨域訪問(wèn)

到此這篇關(guān)于Python web框架fastapi中間件的使用,CORS跨域詳解的文章就介紹到這了,更多相關(guān)Python fastapi中間件內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Numpy 數(shù)組操作之元素添加、刪除和修改的實(shí)現(xiàn)

    Numpy 數(shù)組操作之元素添加、刪除和修改的實(shí)現(xiàn)

    本文主要介紹了Numpy 數(shù)組操作之元素添加、刪除和修改的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-03-03
  • Python如何實(shí)現(xiàn)一個(gè)CLI命令行功能

    Python如何實(shí)現(xiàn)一個(gè)CLI命令行功能

    Click是一個(gè)強(qiáng)大的Python庫(kù),專門用于快速創(chuàng)建命令行界面,本文將詳細(xì)介紹Click庫(kù)的功能以及CLI的應(yīng)用場(chǎng)景,并通過(guò)具體代碼示例展示如何實(shí)現(xiàn)CLI,有需要的可以了解下
    2025-02-02
  • 詳解Python中的strftime()方法的使用

    詳解Python中的strftime()方法的使用

    這篇文章主要介紹了詳解Python中的strftime()方法的使用,是Python入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下
    2015-05-05
  • ansible作為python模塊庫(kù)使用的方法實(shí)例

    ansible作為python模塊庫(kù)使用的方法實(shí)例

    ansible是一個(gè)python package,是個(gè)完全的unpack and play軟件,對(duì)客戶端唯一的要求是有ssh有python,并且裝了python-simplejson包,部署上簡(jiǎn)單到發(fā)指。下面這篇文章就給大家主要介紹了ansible作為python模塊庫(kù)使用的方法實(shí)例,需要的朋友可以參考借鑒。
    2017-01-01
  • python 獲取微信好友列表的方法(微信web)

    python 獲取微信好友列表的方法(微信web)

    今天小編就為大家分享一篇python 獲取微信好友列表的方法(微信web),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2019-02-02
  • python創(chuàng)建列表并給列表賦初始值的方法

    python創(chuàng)建列表并給列表賦初始值的方法

    這篇文章主要介紹了python創(chuàng)建列表并給列表賦初始值的方法,涉及Python列表的定義與賦值技巧,需要的朋友可以參考下
    2015-07-07
  • Python幾種繪制時(shí)間線圖的方法

    Python幾種繪制時(shí)間線圖的方法

    這篇文章主要介紹了Python幾種繪制時(shí)間線圖的方法,Matplotlib 作為 Python 家族最為重要的可視化工具,其基本的 API 以及繪制流程還是需要掌握的
    2022-08-08
  • Python利用format函數(shù)實(shí)現(xiàn)對(duì)齊打印(左對(duì)齊、右對(duì)齊與居中對(duì)齊)

    Python利用format函數(shù)實(shí)現(xiàn)對(duì)齊打印(左對(duì)齊、右對(duì)齊與居中對(duì)齊)

    format是字符串內(nèi)嵌的一個(gè)方法,用于格式化字符串,下面這篇文章主要給大家介紹了關(guān)于Python利用format函數(shù)實(shí)現(xiàn)對(duì)齊打印(左對(duì)齊、右對(duì)齊與居中對(duì)齊)的相關(guān)資料,需要的朋友可以參考下
    2022-04-04
  • Python Pyecharts繪制箱線圖詳解

    Python Pyecharts繪制箱線圖詳解

    箱形圖(Box-plot)又稱為盒須圖、盒式圖或箱線圖,是一種用作顯示一組數(shù)據(jù)分散情況資料的統(tǒng)計(jì)圖。因形狀如箱子而得名。本文將通過(guò)Python Pyecharts來(lái)繪制一些箱線圖,需要的可以參考一下
    2022-03-03
  • python經(jīng)典練習(xí)百題之猴子吃桃三種解法

    python經(jīng)典練習(xí)百題之猴子吃桃三種解法

    這篇文章主要給大家介紹了關(guān)于python經(jīng)典練習(xí)百題之猴子吃桃三種解法的相關(guān)資料, Python猴子吃桃子編程是一個(gè)趣味性十足的編程練習(xí),在這個(gè)練習(xí)中,我們將要使用Python語(yǔ)言來(lái)模擬一只猴子吃桃子的過(guò)程,需要的朋友可以參考下
    2023-10-10

最新評(píng)論