Python web框架fastapi中间件的使用,CORS跨域详解

简介: Python web框架fastapi中间件的使用,CORS跨域详解





fastapi中间件与CORS

1、中间件

你可以向 FastAPI 应用添加中间件。

fastapi "中间件"是一个函数,它在每个请求被特定的路径操作处理之前,以及在每个响应之后工作.

它接收你的应用程序的每一个请求.

然后它可以对这个请求做一些事情或者执行任何需要的代码.

然后它将请求传递给应用程序的其他部分 (通过某种路径操作).

然后它获取应用程序生产的响应 (通过某种路径操作).

它可以对该响应做些什么或者执行任何需要的代码.

然后它返回这个 响应.

请求与响应中间件,并不是需要每次都要写


根据业务需求

例如:如果向做个请求拦截中间件,拦截那些非法请求的ip,只需要在请求中间件中做限制即可,无需让该用户的请求到达业务逻辑层

如果想做响应给每个用户的页面添加个作者信息的响应头,不需要在业务代码每个逻辑都做,只需要在响应中间件处做个响应中间件即可

当然,也有两个中间件都用到的,例如测试请求的响应时间

1.创建中间件方法

要创建中间件你可以在函数的顶部使用装饰器 @app.middleware(“http”).

中间件参数接收如下参数:

  • request.
  • 一个函数call_next,它将接收request,作为参数,然后执行下一个中间件.
  • 这个函数将 request 传递给相应的 路径操作.
  • 然后它将返回由相应的路径操作生成的 response.
  • 然后你可以在返回 response 前进一步修改它.


请求中间件函数在最下面的最先执行

案例:

import time

from fastapi import FastAPI  # FastAPI 是一个为你的 API 提供了所有功能的 Python 类。
import uvicorn

from fastapi import Request


#创建应用程序,app是应用程序名
app = FastAPI()  # 这个实例将是创建你所有 API 的主要交互对象。这个 app 同样在如下命令中被 uvicorn 所引用




#定义中间件m2
@app.middleware('http') #全局中间件
async def m2(request:Request,call_next):
    #请求代码块
    print("m2 request")
    response = await call_next(request)

    #响应代码块
    print("m2 response")
    # 每个中间件的response,都是访问的逻辑函数的响应体
    return response



#定义中间件m1
@app.middleware('http') #全局中间件
async def m1(request:Request,call_next):
    #请求代码块
    print("m1 request")
    response = await call_next(request)


    #响应代码块
    print("m1 response")
    #每个中间件的response,都是访问的逻辑函数的响应体
    return response




@app.get("/user")
def get_user():
    time.sleep(3)
    print("get_user函数执行")
    return {
        "user": "current user"
    }


@app.get("/item/{item_id}")
def get_item(item_id: int):
    time.sleep(2)
    print("get_item函数执行")
    return {
        "item_id": item_id
    }

if __name__ == '__main__':
    #注意,run的第一个参数 必须是文件名:应用程序名
    uvicorn.run("main:app", port=8083,  reload=True,workers=1)


我们测试接口/user,看下请求与响应顺序

请求先走m1中间件,再走m2中间件。然后是逻辑函数响应,然后走走m2中间件响应,最后走m1中间件响应

2.中间件里面添加响应头

#定义中间件m2
@app.middleware('http') #全局中间件
async def m2(request:Request,call_next):
    #请求代码块
    print("m2 request")
    response = await call_next(request)

    #响应代码块
    print("m2 response")
    #添加响应头
    response.headers['author'] = 'jingtian'
    # 每个中间件的response,都是访问的逻辑函数的响应体
    return response

测试,可以看到所有接口,都添加了个响应头

3.在请求处,设置拦截等等

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

访问接口

也可以针对某个接口请求做限制

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


访问/user接口被拒绝

访问其他接口正常

4.测试接口响应时间

可以在最后一个中间件做

#定义中间件m1
@app.middleware('http') #全局中间件
async def m1(request:Request,call_next):
    #请求代码块
    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)

    #响应代码块
    print("m1 response")

    #测试访问结束时间
    end = time.time()
    response.headers["ProcessTimer"] = str(end - start)
    #每个中间件的response,都是访问的逻辑函数的响应体
    return response


我们针对每个接口做了响应时间阻塞

@app.get("/user")
def get_user():
    time.sleep(3)
    print("get_user函数执行")
    return {
        "user": "current user"
    }


@app.get("/item/{item_id}")
def get_item(item_id: int):
    time.sleep(2)
    print("get_item函数执行")
    return {
        "item_id": item_id
    }

测试,/item接口响应时间为2秒多

/user接口响应时间,响应3秒多

2、CORS

1.同源策略带来的跨域问题

在前后端分离的项目中,前端和后端如果部署在同一个服务器,那么运行端口肯定不一样

当前端发起请求到后端,这个时候发送的首先是 option 请求,而不是真正的请求

后端拿到 option 请求后先判断有没有资格(权限),如果没有就会报错;如果有,则会继续请求你真正发起的请求

一句话总结:在浏览器中运行的前端编写了和服务端通信的 JavaScript 代码,而服务端与前端处于不同“源”的情况

协议相同+域名相同+端口号相同,浏览器才认为是同一个网站,才不会受到同源策略的影响,才可以正常的发送Ajax请求

2.跨域的解决方法

因为浏览器同源策略,也正是有了跨域限制,才使我们能安全的上网

但是在实际开发中,有时候需要突破这样的限制,所以就诞生了 CORS

3.CORS

Cross-Origin Resource Sharing 跨域资源共享

是一种基于 HTTP Headers 的机制,该机制通过允许服务器标示除了它自己以外的其它origin(域名,协议和端口),这样浏览器可以访问加载这些跨域资源

CORS 还通过一种机制来检查服务器是否会允许要发送的真实请求,该机制通过浏览器发起一个到服务器托管的跨源资源的"预检"请求

在预检中,浏览器发送的 Headers 中标示有 HTTP 方法和真实请求中会用到的头案例:

后端代码:

from fastapi import FastAPI  # FastAPI 是一个为你的 API 提供了所有功能的 Python 类。
import uvicorn


#创建应用程序,app是应用程序名
app = FastAPI()  # 这个实例将是创建你所有 API 的主要交互对象。这个 app 同样在如下命令中被 uvicorn 所引用




@app.get("/user")
def get_user():
    print("user:jingtian", )
    return {
        "user": "jingtian"
    }


if __name__ == '__main__':
    #注意,run的第一个参数 必须是文件名:应用程序名
    uvicorn.run("CORS:app", port=8080,  reload=True)


创建个前端页面

<!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>

我们在本地用浏览器将html文件打开,可以看到协议,域名都与服务端不同

此时,我们点击click,可以看到出现了同源跨域拦截

后端改造,实现CORS,资源跨域共享

添加个响应中间件

1.方式一


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

此时再在页面点击click,拿到数据

看下响应头,就有了我们添加的响应头 Access-Control-Allow-Origin

如果只允许部分网站来访问,那么就不要用*,使用允许访问的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=["*"],
)

默认情况下,CORSMiddleware 默认实现的参数较为保守,因此需要显式地启用特定的源、方法或者 headers,以便浏览器能够在跨域上下文中使用它们。


支持以下参数:


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。点击,也能实现跨域访问

相关文章
|
6月前
|
开发框架 前端开发 Go
【GoGin】(0)基于Go的WEB开发框架,GO Gin是什么?怎么启动?本文给你答案
Gin:Go语言编写的Web框架,以更好的性能实现类似Martini框架的APInet/http、Beego:开源的高性能Go语言Web框架、Iris:最快的Go语言Web框架,完备的MVC支持。
572 1
|
10月前
|
开发框架 JSON 中间件
Go语言Web开发框架实践:路由、中间件、参数校验
Gin框架以其极简风格、强大路由管理、灵活中间件机制及参数绑定校验系统著称。本文详解其核心功能:1) 路由管理,支持分组与路径参数;2) 中间件机制,实现全局与局部控制;3) 参数绑定,涵盖多种来源;4) 结构体绑定与字段校验,确保数据合法性;5) 自定义校验器扩展功能;6) 统一错误处理提升用户体验。Gin以清晰模块化、流程可控及自动化校验等优势,成为开发者的优选工具。
|
Java API 数据库
构建RESTful API已经成为现代Web开发的标准做法之一。Spring Boot框架因其简洁的配置、快速的启动特性及丰富的功能集而备受开发者青睐。
【10月更文挑战第11天】本文介绍如何使用Spring Boot构建在线图书管理系统的RESTful API。通过创建Spring Boot项目,定义`Book`实体类、`BookRepository`接口和`BookService`服务类,最后实现`BookController`控制器来处理HTTP请求,展示了从基础环境搭建到API测试的完整过程。
487 4
|
10月前
|
开发框架 安全 前端开发
Go Web开发框架实践:模板渲染与静态资源服务
Gin 是一个功能强大的 Go Web 框架,不仅适用于构建 API 服务,还支持 HTML 模板渲染和静态资源托管。它可以帮助开发者快速搭建中小型网站,并提供灵活的模板语法、自定义函数、静态文件映射等功能,同时兼容 Go 的 html/template 引擎,具备高效且安全的页面渲染能力。
|
10月前
|
开发框架 JSON 中间件
Go语言Web开发框架实践:使用 Gin 快速构建 Web 服务
Gin 是一个高效、轻量级的 Go 语言 Web 框架,支持中间件机制,非常适合开发 RESTful API。本文从安装到进阶技巧全面解析 Gin 的使用:快速入门示例(Hello Gin)、定义 RESTful 用户服务(增删改查接口实现),以及推荐实践如参数校验、中间件和路由分组等。通过对比标准库 `net/http`,Gin 提供更简洁灵活的开发体验。此外,还推荐了 GORM、Viper、Zap 等配合使用的工具库,助力高效开发。
|
12月前
|
人工智能 自然语言处理 JavaScript
测试工程师要失业?Magnitude:开源AI Agent驱动的端到端测试框架,让Web测试更智能,自动完善测试用例!
Magnitude是一个基于视觉AI代理的开源端到端测试框架,通过自然语言构建测试用例,结合推理代理和视觉代理实现智能化的Web应用测试,支持本地运行和CI/CD集成。
1885 15
测试工程师要失业?Magnitude:开源AI Agent驱动的端到端测试框架,让Web测试更智能,自动完善测试用例!
|
开发框架 搜索推荐 数据可视化
Django框架适合开发哪种类型的Web应用程序?
Django 框架凭借其强大的功能、稳定性和可扩展性,几乎可以适应各种类型的 Web 应用程序开发需求。无论是简单的网站还是复杂的企业级系统,Django 都能提供可靠的支持,帮助开发者快速构建高质量的应用。同时,其活跃的社区和丰富的资源也为开发者在项目实施过程中提供了有力的保障。
1002 157
|
中间件 关系型数据库 数据库
docker快速部署OS web中间件 数据库 编程应用
通过Docker,可以轻松地部署操作系统、Web中间件、数据库和编程应用。本文详细介绍了使用Docker部署这些组件的基本步骤和命令,展示了如何通过Docker Compose编排多容器应用。希望本文能帮助开发者更高效地使用Docker进行应用部署和管理。
398 19
|
JSON 安全 中间件
Python Web 框架 FastAPI
FastAPI 是一个现代的 Python Web 框架,专为快速构建 API 和在线应用而设计。它凭借速度、简单性和开发人员友好的特性迅速走红。FastAPI 支持自动文档生成、类型提示、数据验证、异步操作和依赖注入等功能,极大提升了开发效率并减少了错误。安装简单,使用 pip 安装 FastAPI 和 uvicorn 即可开始开发。其优点包括高性能、自动数据验证和身份验证支持,但也存在学习曲线和社区资源相对较少的缺点。
638 15
|
设计模式 前端开发 数据库
Python Web开发:Django框架下的全栈开发实战
【10月更文挑战第27天】本文介绍了Django框架在Python Web开发中的应用,涵盖了Django与Flask等框架的比较、项目结构、模型、视图、模板和URL配置等内容,并展示了实际代码示例,帮助读者快速掌握Django全栈开发的核心技术。
846 45

热门文章

最新文章

下一篇
开通oss服务