bigywater.tech
Flask · 25

路由冲突如何解决

两个路由的 URL 一样会怎样?endpoint 重名会怎样?应用和蓝图抢同一个地址谁赢?这篇把几种冲突都造出来,并给出启动时检查的办法。

先注册赢
同一 URL 被不同端点注册时的结果(应用或蓝图都一样)
AssertionError
不同函数同 endpoint 时的报错
ValueError
同一蓝图不加 name= 注册两次时的报错

endpoint 冲突

实测 · 本机执行输出
  同名函数 → AssertionError: View function mapping is overwriting an existing endpoint function: page
  同一个函数对象用同一个 endpoint 注册第二个 URL → 允许(同一函数)

上一篇:OPTIONS 与 HEAD 自动处理;下一篇:Blueprint 路由注册;匹配优先级:URL Rule 与路由匹配顺序。

规则冲突

实测 · 本机执行输出
  GET /x → first | 规则列表: [('/x', 'first'), ('/x', 'second')]

应用与蓝图

实测 · 本机执行输出
  先注册应用路由、后注册蓝图 → GET /hello: from app
  先注册蓝图、后注册应用路由 → GET /hello: from bp

同一蓝图注册两次

实测 · 本机执行输出
  第二次注册同名蓝图 → ValueError: The name 'multi' is already registered for this blueprint. Use 'name=' to provide a unique name.
  加 name="multi_v2" 后: {'/v1/ping': 200, '/v2/ping': 200} | endpoints: ['multi.ping', 'multi_v2.ping']

通配路由

实测 · 本机执行输出
   {'/about': 'about', '/api/users': 'users', '/api/x': 'catch:api/x', '/zzz/yyy': 'catch:zzz/yyy'}

启动时检查

实测 · 本机执行输出
  冲突检查结果: [('/x', 'GET', 'x1', 'x3')]
  (/u/<int:i> 与 /u/<name> 参数名不同、归一化后模式也不同,没有被报出来;这个简化脚本只能发现「模式与方法完全相同」的冲突)

flask routes --sort

实测 · 本机执行输出
  --sort endpoint  → 端点顺序 ['alpha', 'alpha_post', 'static', 'zeta']
  --sort rule      → 端点顺序 ['alpha', 'alpha_post', 'zeta', 'static']
  --sort methods   → 端点顺序 ['static', 'zeta', 'alpha', 'alpha_post']

分步演示

路由冲突
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 arm64 / Python 3.14.7 / Flask 3.1.3 / Werkzeug 3.1.9 / Jinja2 3.1.6 / SQLAlchemy 2.1.1 / gunicorn 26.2.0(都装在自己的虚拟环境里);大多数实验用 Flask 的 test_client(直接调用 WSGI 应用,不经过网络),需要真实 HTTP 时另起 gunicorn 或开发服务器(端口 9600 以上,本机 127.0.0.1);计时用 time.perf_counter,数字每次运行会有小幅抖动
    • 没有验证:subdomain / host_matching 下的冲突、方法集合部分重叠(如一条 GET、一条 GET+POST)时的优先、第三方扩展(如 Flask-RESTful)注册路由时的冲突提示
    • 启动时检查的脚本是本篇自己写的简化版,不是 Flask 内置功能
    京ICP备2026067502号-1京公网安备11010502063487号