【Fastapi学习笔记(1)】
鉴权、传附加信息、控制请求场景:登录 token、版本、设备、格式特点:手动传,前后端分离主流就是服务器在返回数据时,额外塞给客户端的一段“小信息”。它不在返回的 JSON 里,而是藏在响应的头部。客户端(浏览器/前端)可以拿到,但用户看不见。传递额外信息,不污染业务数据不想把状态、版本、提示放进 JSON,就放响应头。控制前端行为让浏览器缓存、跨域、不缓存、重定向等。安全控制防劫持、防XSS、防
- 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?好处是什么?
-
类型更干净
不用写 = Depends() 在后面 -
官方推荐风格
-
可以放多个依赖 / 元数据
Annotated[User, Depends(get_user), Depends(check_token)] -
代码更统一、更优雅
-
字典 跟 json 的区别?
长得很像,但完全不是一回事!
- 字典 (dict):是 Python 内存里的对象,给代码用的
- 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
浏览器/客户端发请求时,附带的附加信息包,放在请求报文头部,服务端用来识别、校验、适配请求。
常见作用:
- 告诉服务器客户端类型、浏览器、系统
- 携带认证令牌、权限标识
- 声明能接收的数据格式、编码
- 跨域、防盗链校验
常用字段
User-Agent:客户端设备与浏览器信息Content-Type:请求体数据格式(JSON/表单)Authorization:登录令牌鉴权Referer:来源页面地址
二、Cookie
服务器下发、存在浏览器本地的小型文本数据,跟随每次请求自动带回服务端。
核心用途
- 记录登录状态,维持会话
- 保存用户偏好、临时标识
- 识别同一访客身份
特点
- 大小有限,只存简单字符串
- 可设置过期时间
- 每次同源请求自动携带发送
三者关系直白类比
- 请求体:真正要提交的业务数据(表单、参数)
- 请求头:附带说明、身份凭证、格式说明
- Cookie:随身身份小卡片,自动跟着请求走
一句话区分
请求头是通用附加说明;Cookie是存本地、自动携带的身份小数据。
请求头和cookie在fastapi中的作用以及使用场景有哪些?
一、先记住一句话
请求头 = 快递单上的所有信息
Cookie = 快递单里的「身份贴条」
在 FastAPI 里:
- 请求头:用来识别、鉴权、控制请求
- Cookie:用来记住用户、保持登录状态
二、请求头 Header 在 FastAPI 里的作用
作用
- 传递身份凭证(token)
- 告诉接口数据格式
- 做权限校验
- 做跨域、防盗链、设备识别
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 里的作用
作用
- 自动记住用户(不用每次都传 token)
- 保持登录状态
- 存储少量用户信息
- 识别访客
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 里,而是藏在响应的头部。
客户端(浏览器/前端)可以拿到,但用户看不见。
二、自定义响应头有什么用?(核心作用)
-
传递额外信息,不污染业务数据
不想把状态、版本、提示放进 JSON,就放响应头。 -
控制前端行为
让浏览器缓存、跨域、不缓存、重定向等。 -
安全控制
防劫持、防XSS、防盗链。 -
接口监控、调试、日志
传请求ID、处理时间、服务版本。 -
权限/状态标记
告诉前端是否需要刷新登录、限流等。
三、最常用的应用场景(真实开发 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
五、一句话记住自定义响应头
不污染返回数据,又能给前端传秘密信息、控制行为、加强安全、方便调试。
它是后端和前端之间的悄悄话通道。
六、最简单总结(必背)
自定义响应头的作用:
- 传额外信息
- 控制浏览器/前端行为
- 加强安全
- 方便调试、日志、监控
使用场景:
- 跨域
- 缓存控制
- 请求ID、耗时
- 安全防护
- Token 过期提醒
- 接口版本
- 文件下载
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐

所有评论(0)