
升级 Flask 至 3.1.0 后,依赖 SERVER_NAME 实现子域名(如 user.domain.com)的路由全部返回 404,根本原因是子域名匹配机制默认关闭,必须显式启用 subdomain_matching=True 并正确配置 SERVER_NAME。
升级 flask 至 3.1.0 后,依赖 `server_name` 实现子域名(如 user.domain.com)的路由全部返回 404,根本原因是子域名匹配机制默认关闭,必须显式启用 `subdomain_matching=true` 并正确配置 `server_name`。
Flask 3.1.0 对子域名支持进行了关键性调整:SERVER_NAME 参数不再隐式启用子域名路由匹配。即使你仍设置 SERVER_NAME = "domain.com" 和 SESSION_COOKIE_DOMAIN = ".domain.com",若未显式启用 subdomain_matching,Flask 将完全忽略路由中的 subdomain 参数(例如 @bp.route('/', subdomain='
✅ 正确做法是:在创建 Flask 应用实例时,必须显式传入 subdomain_matching=True:
from flask import Flask, request
app = Flask(
__name__,
subdomain_matching=True # ← 关键!必须显式启用
)
app.config['SERVER_NAME'] = 'domain.com' # 必须与实际域名一致(不含协议、端口)
app.config['SESSION_COOKIE_DOMAIN'] = '.domain.com' # 支持所有子域名共享会话
⚠️ 注意事项:
- SERVER_NAME 必须严格匹配实际访问的主域名(如 domain.com),不能是 www.domain.com 或带端口(如 domain.com:5000),否则子域名解析失败;
- 启用 subdomain_matching=True 后,Flask 才会基于 SERVER_NAME 解析 Host 头中的子域名,并与路由定义中的 subdomain 字段进行匹配;
- 蓝图注册时无需额外配置,但需确保其路由明确指定 subdomain(如 @bp.route('/dashboard', subdomain='
')); - 开发环境下建议使用本地 hosts 文件模拟子域名(如 127.0.0.1 user1.domain.com user2.domain.com),并配合 SERVER_NAME=domain.com 测试;
- 若使用 WSGI 服务器(如 Gunicorn/Nginx),需确保反向代理正确透传 Host 请求头,避免被覆盖。
? 总结:Flask 3.1.0 将子域名功能从“隐式依赖 SERVER_NAME”改为“显式 opt-in 模式”。这不是 Bug,而是更清晰的责任分离设计——SERVER_NAME 仅用于解析请求主机名,而子域名路由逻辑由 subdomain_matching 开关独立控制。务必检查应用初始化代码,补上 subdomain_matching=True,即可无缝恢复 user.domain.com 等动态子域名功能。










