catch-all路由

news2025/4/8 16:04:35

介绍

✅ 什么是 Catch-All 路由?

Catch-All 路由 指的是:一个能匹配“任意路径”的通配型路由。

它一般会使用 路径参数 path 类型,比如:

@app.get("/{full_path:path}")
async def fallback_handler(full_path: str):
    return {"msg": f"You visited: {full_path}"}

这个 / 开头的 /{full_path:path},意思是:
• 匹配任何以 / 开头的请求;
• 把完整的路径作为字符串传入 full_path;
• 哪怕路径是 /foo/bar/hello.jpg,它也能匹配!

所以叫 Catch-All,就像“最后一个网兜”,你没被其他精确路径命中,就会掉进去。

URL 路由匹配机制的一部分,和代码有没有 try-catch 是两码事。

部分含义
/所有路径的开头
{full_path}这是一个路径参数,名字叫 full_path
:path是这个参数的“类型转换器”

🔍 :path 是什么意思?

类型描述
str默认,只匹配不含斜杠 / 的一段
int匹配整数
float匹配浮点数
path✅ 匹配多段路径(包括斜杠 /)

就意味着这个路由会匹配所有请求路径,无论路径有多少层!

也正因如此,它常被叫做 Catch-All(兜底)路由,用于前端 SPA 项目的前端路由支持。

@app.get("/api/user")
def user(): ...

@app.get("/api/task")
def task(): ...

@app.get("/{path:path}")
def fallback(path): ...

访问 /api/user 会进入 user(),访问 /api/task 会进入 task()。

但如果你访问:

• /api/does-not-exist → ❗ 不会 404!

• 会进入 fallback(path),path == “api/does-not-exist”

这就叫 Catch-All。

路由顺序

  1. 它是匹配所有路径的,如果注册早了,就会“截胡”所有后面的路由。

  2. FastAPI 按照注册顺序来判断匹配优先级,谁先注册,谁优先。

  3. 如果 Catch-All 早注册,那就没有“后面”了,你的 /api/v1/** 根本用不上!

🎯 问题核心:setup_admin(app) 是个「兜底路由(catch-all)」

SQLAdmin 或类似的后台管理插件,一般都会注册一个这样的路由:

@app.get("/{full_path:path}")
async def catch_all_route(full_path: str): ...

🚨 所有未被上面 include_router 明确匹配到的路径请求,都会被这个 catch-all 捕获处理。

• 本来这个应该走 user_router 的 CORS 预检流程;

但是如果这个路由在 setup_admin(app) 之后注册了,那么 catch-all 路由先注册,它就优先匹配了!

• 而 catch-all 路由并不会处理跨域(CORS OPTIONS 请求);

• 所以浏览器就报了 CORS 跨域错误 ⚠️

# 1. 注册所有业务接口
app.include_router(api_router1)
app.include_router(api_router2)

# 2. 注册 SQLAdmin(会用 catch-all)
setup_admin(app)

# 3. 注册前端静态资源路由(if any)
app.include_router(web_router.router)

路由找不到报CORS?

FastAPI 的中间件执行顺序 + catch-all 路由的作用范围 + CORS 的工作机制

app.add_middleware(
    CORSMiddleware,  # 跨域处理
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],  # 允许所有方法
    allow_headers=["*"],  # 允许所有头部
)

✅ 你已经注册了 CORSMiddleware,那为啥还报跨域?

上述代码:

所有经过 FastAPI 路由匹配成功的请求(包括 OPTIONS 预检请求)都会自动添加 Access-Control-Allow-* 相关响应头从而避免跨域错误!

❌ 但为什么“未命中的路由”还会报跨域?

这是核心重点:

🔥CORS 中间件只作用于:能被 FastAPI 接收到的请求

⚠️ 如果这个 Catch-All 路由没有处理 CORS,结果就是:

  1. 浏览器先发出 预检请求 OPTIONS /api/v1/xxx

  2. FastAPI 查找路由匹配不到(因为这个接口没注册或被覆盖);

  3. 匹配到你的 Catch-All;

  4. 但 Catch-All 没有注册 OPTIONS 方法;

  5. FastAPI 返回 405 或 404;

  6. CORSMiddleware 不生效(它只对合法路由生效);

  7. 浏览器就 报跨域错误

这一段已经告诉 FastAPI:我允许跨域请求,包括 OPTIONS 方法。

但!!!问题的关键不是你有没有加 allow_methods=[“*”],而是:

❗ 请求路径 /some/path 根本没注册任何路由!也就没有任何 handler 能接住 OPTIONS 请求!

你要知道:

FastAPI 的 CORS 中间件只会对 存在的路由 生效

❌ 所以:如果你的某个路径根本没被 app.include_router() 注册

比如请求的是 /aichat/pub_agent/expend/dict/,但你没有注册它,那么:

• FastAPI 连 OPTIONS 都不知道该交给谁处理

• 它直接走到了 404 或 405

• 然后 CORS middleware 根本不会处理它

• ✅ 最终结果:浏览器就看到一个没有 CORS headers 的响应,报 CORS error

[请求进来]
     ↓
中间件先处理 (CORSMiddleware 会拦截 OPTIONS 请求)
     ↓
如果请求路径存在 → CORSMiddleware 会自动响应 OPTIONS 并添加 CORS headers ✅
     ↓
如果请求路径不存在 → 中间件不处理,FastAPI 抛出 404

✔ 方法一:确认你的 catch-all 路由支持 OPTIONS 请求

@router.api_route("/{full_path:path}", methods=["GET", "POST", "OPTIONS"])
async def catch_all(full_path: str, request: Request):
    ...

⚠️ 即使你什么都不做,也得让它 return 一个空的响应,这样 CORSMiddleware 就会处理它。

✔ 方法二:手动添加一个兜底的 OPTIONS 响应

from fastapi.responses import Response

@router.options("/{full_path:path}")
async def options_handler(full_path: str):
    return Response()
原因说明
CORS 中间件只对匹配成功的路由生效OPTIONS 预检必须也要命中
Catch-All 如果不支持 OPTIONS,就会报错浏览器就会认为是跨域失败
路由顺序、注册方式影响是否生效后注册的 Catch-All 可能覆盖其他逻辑

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2327110.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

jdk21新特性详解使用总结

jdk21新特性详解总结 1.StringBuilder和StringBuffer新增了一个repeat方法 /*** Java 21的StringBuilder和StringBuffer新增了一个repeat方法*/public static void repeatStr(){var sbnew StringBuilder().repeat("*",10);System.out.println(sb);}运行结果如下&…

【实用技巧】电脑重装后的Office下载和设置

写在前面:本博客仅作记录学习之用,部分图片来自网络,如需引用请注明出处,同时如有侵犯您的权益,请联系删除! 文章目录 前言下载设置总结互动致谢参考目录导航 前言 在数字化办公时代,Windows和…

206. 反转链表 92. 反转链表 II 25. K 个一组翻转链表

leetcode Hot 100系列 文章目录 一、翻转链表二、反转链表 II三、K 个一组翻转链表总结 一、翻转链表 建立pre为空,建立cur为head,开始循环:先保存cur的next的值,再将cur的next置为pre,将pre前进到cur的位置&#xf…

离线语音识别 ( 小语种国家都支持)可定制词组

1产品介绍 离线语音模组采用神经网络算法,支持语音识别、自学习等功能。运用此模组将 AI 技 术赋能产品,升级改造出语音操控的智能硬件 ( 例如风扇、台灯、空调、马桶、按摩椅、运 动相机、行车记录仪等 ) 。支持全球多种语言识别,如中文…

网络华为HCIA+HCIP 策略路由,双点双向

目录 路由策略,策略路由 策略路由优势 策略路由分类 接口策略路由 双点双向 双点双向路由引入特点: 联系 路由回灌和环路问题 路由策略,策略路由 路由策略:是对路由条目进行控制,通过控制路由条目影响报文的转发路径,即路…

【TI MSPM0】ADC DAC学习

一、样例展示 通过ADC0触发单次采样,如果采样结果大于0.5倍的VDD,就点亮LED 否则熄灭LED 编译加载运行这个历程,提供一个电压到A0_2引脚上,电压范围在0-VCC之间同时观察LED1.在上电后,默认将ADC配置到正确的引脚模式,…

Cesium系列:从入门到实践,打造属于你的3D地球应用

一、Cesium简介 CesiumJS 是一个开源的 JavaScript 库,它能够帮助开发者创建出具有卓越性能、高精度、出色视觉质量和易用性的世界级 3D 地球仪和地图。无论是在航空航天领域,用于模拟飞行路径和展示卫星数据;还是在智能城市中,用…

Linux系统程序设计:从入门到高级Day01

知识点1 【系统调用】 系统调用的概述 系统调用:内核 提供给 用户 可以 操作内核 的一组函数接口 关系:用户 借助 系统调用 操作内核 进程的空间分为:内核空间 和 用户空间 用户一般都是在用户空间操作的,但是有的时候用户需要…

openEuler24.03 LTS下安装HBase集群

前提条件 安装好Hadoop完全分布式集群,可参考:openEuler24.03 LTS下安装Hadoop3完全分布式 安装好ZooKeeper集群,可参考:openEuler24.03 LTS下安装ZooKeeper集群 HBase集群规划 node2node3node4MasterBackup MasterRegionServ…

关于testng.xml无法找到类的问题

问题:testng.xml添加测试类的时候飘红 解决办法: 1.试图通过自动生成testng.xml插件去解决,感觉也不是这个问题,没有尝试; 2.以为是创建包的方式不对,重新删除后新建--还是找不到 想新建类的时候发现从m…

数据结构:探秘AVL树

本节重点 理解AVL树的概念掌握AVL树正确的插入方法利用_parent指针正确更新平衡因子掌握并理解四种旋转方式:左单旋,右单旋,左右双旋,右左双旋 一、AVL树的概念 AVL树得名于它的发明者G. M. Adelson-Velsky和E. M. Landis&…

Linux 入门:基础开发工具(上)vim,gcc/g++,make/makefile

目录 一.软件包管理器 一).软件包 二).安装软件 三).删除软件 二.编辑器vim 一).vim的基本介绍 1.正常/普通/命令模式(Normal mode) 2.插入模式(Insert mode) 3.底行模式(last line mode) 二).vim的基本操作 …

5、无线通信基站的FPGA实现架构

基站(Base Station,BS),也称为公用移动通信基站,是无线电台站的一种形式,具体则指在一定的无线电覆盖区中,通过移动通信交换中心,与移动电话终端之间的信息传递的无线电收发信电台。…

Linux2 CD LL hostnamectl type mkdir dudo

查看主机名信息 设置静态主机名 同时配置静态、瞬时主机名 下载Vmware tools https://blog.csdn.net/qq_34638161/article/details/102779721 mkdir创建目录 问题:为什么在root目录下 看不到 /var /usr那些文件夹

Docker容器部署Java项目的自动化脚本(Shell编写)

🤟致敬读者 🟩感谢阅读🟦笑口常开🟪生日快乐⬛早点睡觉 📘博主相关 🟧博主信息🟨博客首页🟫专栏推荐🟥活动信息 文章目录 Docker容器部署Java项目的自动化脚本&#x…

STM32F103C8T6单片机硬核原理篇:讨论GPIO的基本原理篇章1——只讨论我们的GPIO简单输入和输出

目录 前言 输出时的GPIO控制部分 标准库是如何操作寄存器完成GPIO驱动的初始化的? 问题1:如何掌握GPIO的编程细节——跟寄存器如何打交道 问题2:哪些寄存器,去哪里找呢? 问题三,寄存器的含义&#xff…

UniApp集成极光推送详细教程

最近项目要集成推送服务,选型极光推送,记录一下开发过程。 1、极光官网注册登录 1.1选择极光推送产品,新建应用 1.2在下一步中选择Android/IOS的消息推送服务 1.3产品设置中输入应用包名(一经输入后不可更改,一定要正…

AI战略群与星际之门:软银AI投资版图计划深度解析

一、星际之门:万亿美元级 AI 基础设施革命 1.1 项目背景与战略定位 在 AI 技术迅猛发展的今天,算力已成为推动其前进的核心动力。软银联合 OpenAI、甲骨文、英伟达、微软、arm推出的 “星际之门”(Stargate)计划,无疑是 AI 领域的一颗重磅炸弹。作为 AI 领域史上最大单笔…

系统思考与时间管理

时间管理的真正秘诀:主动浪费时间? 巴菲特的私人飞机驾驶员觉得自己不够成功,于是向巴菲特请教应该怎么做。巴菲特让他列出了自己人生中最想实现的25个目标,并按重要程度排序,接着安排时间专注做前五件最重要的事情。…

mac air m系列arm架构芯片安装虚拟机 UTM+debian 浏览器firefox和chrome

成果展示:debian虚拟机,你值得拥有! 预期结果 1、mac的m系列芯片,arm 架构且内存小,安装虚拟机。 考虑到mac m系列芯片8g内存,arm架构想安装一个轻量的虚拟机,偶然之间发现了debian&#xff0c…