• Pydantic 是 Fastapi 的核心依赖,用于数据校验和序列化。它是数据类型校验库,通过使用Python类型注解定义数据结构,它负责自动完成数据校验和转换。通过继承BaseModel类来定义一个Pydantic模型,字段是否必填取决于是否有默认值,没有默认值的字段为必填。
  • Fastapi 响应数据都会自动将返回结果转换成 json 格式,发送给客户端(给人看的)。也就是不管你路由函数返回的是字典,还是Pydantic模型实例,都会自动转换成json格式。
  • 依赖注入:一种设计模式,让你可以将通用的逻辑(如数据库连接、身份验证、参数校验等)提取为可复用的组件,然后在路由中按需使用。Fastapi会在执行路由函数之前自动调用依赖函数,并将返回值传递给路由函数。

依赖函数和路径操作函数使用相同的参数声明方式,FastAPI 会自动解析依赖函数的参数。这意味着依赖函数也可以使用查询参数、路径参数、请求体等。

依赖函数里可以直接写:
查询参数 q: str
路径参数 user_id: int
请求头 token: str = Header()
Cookie session_id: str = Cookie()
请求体模型 user: User
甚至其他依赖
FastAPI 全部自动解析。


class CommonQueryParams:
    def __init__(self, q: str | None = None, skip: int = 0, limit: int = 100):
        self.q = q
        self.skip = skip
        self.limit = limit

# 使用类作为依赖
@app.get("/items/")
async def read_items(commons: Annotated[CommonQueryParams, Depends()]):
    return {"q": commons.q, "skip": commons.skip, "limit": commons.limit}
  • Annotated: 是 Python 官方语法(3.9+)作用:给类型加 “附加信息”
    格式:

    Annotated[类型, 附加信息1, 附加信息2...]
    
  • Depends() 是什么?
    平时我们写依赖是:

    Depends(函数名)
    

    但这里是类,不是函数,所以 FastAPI 允许你简写:

    Depends()  # 自动用前面的类作为依赖
    

下面两种写法功能完全一样!
写法 A(你给的,优雅)

async def read_items(commons: Annotated[CommonQueryParams, Depends()]):

写法 B(原始写法,啰嗦)

async def read_items(commons: CommonQueryParams = Depends()):
  • 为什么要用 Annotated?好处是什么?
    1. 类型更干净
      不用写 = Depends() 在后面

    2. 官方推荐风格

    3. 可以放多个依赖 / 元数据

      Annotated[User, Depends(get_user), Depends(check_token)]
      
    4. 代码更统一、更优雅


字典 跟 json 的区别?

长得很像,但完全不是一回事!

  1. 字典 (dict):是 Python 内存里的对象,给代码用的
  2. JSON:是 纯文本字符串,给网络/文件用的

直观对比

1. Python 字典(代码里的)

# 这是 Python 对象,运行在内存里
person = {
    "name": "小明",
    "age": 20,
    "is_student": True,    # 大写 T
    "hobby": None          # None 表示空
}

特点:

  • 引号:单双引号都行 ' "
  • 布尔值True / False(大写)
  • 空值None
  • 可以存函数、对象、日期等复杂内容

2. JSON(文本字符串)

{
    "name": "小明",
    "age": 20,
    "is_student": true,    # 小写 t
    "hobby": null          # null
}

特点:

  • 只能用双引号 "绝对不能用单引号
  • 布尔值:true / false(小写)
  • 空值:null
  • 只能是纯文本,不能存函数/对象

核心区别

特性 Python 字典 (dict) JSON
本质 内存数据结构 纯文本字符串
引号 单/双引号都可以 必须双引号
布尔值 True False true false
空值 None null
用途 代码里存数据 网络传输、存文件
注释 支持 不支持

它们的关系:转换

Python 提供了 json 库,帮你互相转换

字典 → JSON(序列化)

import json

# 字典
person = {"name": "小明", "age": 20}

# 转成 JSON 字符串
json_str = json.dumps(person)
print(type(json_str))  # <class 'str'>  变成文本了!

JSON → 字典(反序列化)

# JSON 字符串
json_str = '{"name": "小明", "age": 20}'

# 转成字典
person = json.loads(json_str)
print(type(person))   # <class 'dict'> 变回代码对象

最简单的理解

  • 字典 = 你脑子里想的信息
  • JSON = 写在纸上、发给别人的文字

你要把想法传给别人,必须写下来(转 JSON)
别人收到文字,要理解必须变成想法(转字典)

请求头和 Cookie是什么?

一、请求头 Request Headers

浏览器/客户端发请求时,附带的附加信息包,放在请求报文头部,服务端用来识别、校验、适配请求。

常见作用:

  1. 告诉服务器客户端类型、浏览器、系统
  2. 携带认证令牌、权限标识
  3. 声明能接收的数据格式、编码
  4. 跨域、防盗链校验

常用字段

  • User-Agent:客户端设备与浏览器信息
  • Content-Type:请求体数据格式(JSON/表单)
  • Authorization:登录令牌鉴权
  • Referer:来源页面地址

二、Cookie

服务器下发、存在浏览器本地的小型文本数据,跟随每次请求自动带回服务端。

核心用途

  1. 记录登录状态,维持会话
  2. 保存用户偏好、临时标识
  3. 识别同一访客身份

特点

  • 大小有限,只存简单字符串
  • 可设置过期时间
  • 每次同源请求自动携带发送

三者关系直白类比

  • 请求体:真正要提交的业务数据(表单、参数)
  • 请求头:附带说明、身份凭证、格式说明
  • Cookie:随身身份小卡片,自动跟着请求走

一句话区分

请求头是通用附加说明;Cookie是存本地、自动携带的身份小数据。


请求头和cookie在fastapi中的作用以及使用场景有哪些?

一、先记住一句话

请求头 = 快递单上的所有信息
Cookie = 快递单里的「身份贴条」

在 FastAPI 里:

  • 请求头:用来识别、鉴权、控制请求
  • Cookie:用来记住用户、保持登录状态

二、请求头 Header 在 FastAPI 里的作用

作用

  1. 传递身份凭证(token)
  2. 告诉接口数据格式
  3. 权限校验
  4. 跨域、防盗链、设备识别

FastAPI 中怎么用?

1. 获取请求头
from fastapi import FastAPI, Header

app = FastAPI()

@app.get("/")
def read_root(user_agent: str = Header()):
    return {"你的浏览器信息": user_agent}
2. 最常用场景:从请求头拿 Token 登录鉴权
@app.get("/user/info")
def user_info(authorization: str = Header()):
    # 校验 token 是否正确
    if authorization != "Bearer 123456":
        return {"msg": "未登录"}
    return {"msg": "已登录,欢迎回来"}

请求头使用场景

  • 登录鉴权(最常用
  • 接口版本控制
  • 传递语言、时区
  • 客户端设备判断
  • 接口限流、权限控制

三、Cookie 在 FastAPI 里的作用

作用

  1. 自动记住用户(不用每次都传 token)
  2. 保持登录状态
  3. 存储少量用户信息
  4. 识别访客

FastAPI 中怎么用?

1. 获取 Cookie
from fastapi import Cookie

@app.get("/get-cookie")
def get_cookie(session_id: str | None = Cookie(None)):
    return {"你的会话ID": session_id}
2. 设置 Cookie(登录成功后下发)
from fastapi import Response

@app.get("/login")
def login(response: Response):
    # 给浏览器设置 cookie
    response.set_cookie(key="session_id", value="abc123def")
    return {"msg": "登录成功,cookie已下发"}

Cookie 使用场景

  • 网站登录状态保持
  • 记住我(7天免登录)
  • 购物车、用户偏好
  • 会话识别
  • 后台管理系统登录

四、最关键区别(面试必考)

请求头 Header

  • 手动传
  • 适合接口、APP、小程序
  • 更安全、更灵活
  • 前后端分离首选

Cookie

  • 浏览器自动传
  • 适合网站、网页
  • 自动维持登录
  • 传统 Web 项目用得多

五、FastAPI 开发中最真实的使用场景

1. 90% 前后端分离项目

请求头 + Token

Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

2. 管理后台、网页项目

Cookie + Session

  • 登录成功 → 下发 Cookie
  • 下次访问 → 浏览器自动带上
  • FastAPI 直接读取,判断是否登录

3. 文件下载、接口加密

请求头带签名、时间戳等。

4. 多语言接口

请求头带 Accept-Language 返回对应语言。


六、超级简单总结

请求头 Header

  • 作用:鉴权、传附加信息、控制请求
  • 场景:登录 token、版本、设备、格式
  • 特点:手动传,前后端分离主流

Cookie

  • 作用:记住用户、保持登录
  • 场景:网站登录、购物车、会话
  • 特点:浏览器自动带,适合网页

自定义响应头有什么作用以及应用场景是?

一、什么是自定义响应头?

就是 服务器在返回数据时,额外塞给客户端的一段“小信息”
不在返回的 JSON 里,而是藏在响应的头部。

客户端(浏览器/前端)可以拿到,但用户看不见。


二、自定义响应头有什么用?(核心作用)

  1. 传递额外信息,不污染业务数据
    不想把状态、版本、提示放进 JSON,就放响应头。

  2. 控制前端行为
    让浏览器缓存、跨域、不缓存、重定向等。

  3. 安全控制
    防劫持、防XSS、防盗链。

  4. 接口监控、调试、日志
    传请求ID、处理时间、服务版本。

  5. 权限/状态标记
    告诉前端是否需要刷新登录、限流等。


三、最常用的应用场景(真实开发 90% 都会用到)

1. 跨域配置(最最常用)

Access-Control-Allow-Origin: *

允许前端调用接口,解决跨域报错。

2. 禁止缓存 / 强制刷新

Cache-Control: no-cache

让浏览器每次都拿最新数据,不读本地缓存。
(登录接口、支付接口、实时数据必用)

3. 传递接口处理时间、请求唯一ID(日志排查)

X-Process-Time: 0.032
X-Request-ID: abc123def456

方便查问题:哪个请求慢?哪次调用出错?

4. 安全防护(必加)

X-Content-Type-Options: nosniff
X-XSS-Protection: 1

防止网页被劫持、XSS攻击。

5. 告诉前端:Token 快过期了,需要刷新

X-Token-Expire-Soon: true

前端自动跳登录或刷新token。

6. 接口版本控制

X-API-Version: 2.0

区分新旧接口。

7. 文件下载时告诉浏览器文件名

Content-Disposition: attachment; filename=report.pdf

8. 限流提示

X-RateLimit-Remaining: 5

告诉用户还能调用几次接口。


四、FastAPI 中如何自定义响应头?(直接复制用)

方式1:单个接口返回自定义头

from fastapi import FastAPI, Response

app = FastAPI()

@app.get("/api/data")
def get_data(response: Response):
    # 自定义响应头
    response.headers["X-Process-Time"] = "0.025"
    response.headers["X-API-Version"] = "2.0"
    response.headers["Cache-Control"] = "no-cache"
    
    return {"msg": "数据返回成功"}

方式2:全局统一加响应头(所有接口都带)

from fastapi import FastAPI, Request, Response
from fastapi.responses import JSONResponse

app = FastAPI()

@app.middleware("http")
async def add_custom_header(request: Request, call_next):
    response = await call_next(request)
    
    # 统一给所有接口加响应头
    response.headers["X-Server"] = "FastAPI-Server"
    response.headers["X-Env"] = "Production"
    
    return response

五、一句话记住自定义响应头

不污染返回数据,又能给前端传秘密信息、控制行为、加强安全、方便调试。

它是后端和前端之间的悄悄话通道


六、最简单总结(必背)

自定义响应头的作用:

  1. 传额外信息
  2. 控制浏览器/前端行为
  3. 加强安全
  4. 方便调试、日志、监控

使用场景:

  • 跨域
  • 缓存控制
  • 请求ID、耗时
  • 安全防护
  • Token 过期提醒
  • 接口版本
  • 文件下载

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐