before_request在每次请求进入Flask应用、到达视图函数前必定执行,不区分HTTP方法和路由,但默认不处理静态文件;它仅在WSGI层生效,不能修改response,只能读取request、设置g变量、抛异常或返回响应。

before_request 什么时候执行?
before_request 是 Flask 应用中每个请求进入视图函数前**必定触发**的一次性钩子,不依赖路由、不区分 HTTP 方法,只要匹配到应用(包括 404),它就跑。但它不会对静态文件(如 /static/xxx.js)默认生效——除非你显式配置了 app.static_folder 被包含在请求路径里,且没被 before_request 里的逻辑提前 return。
常见误判是以为它能拦截所有网络流量(比如 CDN 或 Nginx 层的请求),其实它只在 Flask WSGI 层生效;另一个典型错误是把它当成了「中间件」来处理响应,但它**不能修改 response 对象**,只能读取 request、设置 g 变量、抛异常或直接 return 响应。
如何正确注册全局 before_request?
必须在创建 Flask 实例后、调用 app.run() 前注册;如果用了工厂模式(create_app()),要确保在工厂内部完成注册,而不是在模块顶层。
- ✅ 正确:在
app = Flask(__name__)后立刻用@app.before_request装饰器 - ❌ 错误:在蓝图(
Blueprint)里用@bp.before_request—— 这只是该蓝图内生效,不是全局 - ⚠️ 注意:多个
@app.before_request函数按注册顺序执行,但无内置优先级控制,建议用单一函数封装逻辑,避免分散判断
示例:
from flask import Flask, g, request
<p>app = Flask(<strong>name</strong>)</p><p>@app.before_request
def set_user_context():
g.user_id = request.headers.get('X-User-ID')
if not g.user_id:</p><h1>直接终止请求流,返回 401</h1><pre class="brush:php;toolbar:false;"> from flask import abort
abort(401)
让 macOS 自动化像说话一样简单 —— 用代码控制你的 Mac,无需学习 AppleScript 系统要求 macOS 14+ (Sonoma) Python 3.9+ 需要开启:辅助功能 + 屏幕录制权限
为什么 g 变量比全局变量更安全?
Flask 的 g 是请求上下文绑定的临时容器,每个请求独享一份,线程/协程隔离;而普通全局变量(如 current_user = None)会在多请求并发时互相污染。
- ✅ 用
g.token存 JWT 解析结果,后续视图可直接读取 - ❌ 不要用
global user_cache来缓存当前用户,会跨请求泄漏 - ⚠️
g在teardown_request后自动清空,但若在异步任务或子线程中访问,会报RuntimeError: Working outside of application context
常见拦截失败原因排查
遇到 before_request 像没生效一样?先看这几条:
- 是否启用了调试模式但忘了刷新浏览器(缓存了旧响应)?试 curl 加
-H "Cache-Control: no-cache" - 是否在蓝图为
url_prefix='/api'下注册了视图,但请求路径是/health(未匹配任何蓝图)?此时before_request仍会执行,但你可能在日志里漏看了 - 是否在钩子里调用了阻塞 I/O(如同步数据库查询)?这会让整个应用卡住,表现为请求超时而非跳过钩子
- 是否在钩子中 raise 了未被 Flask 捕获的异常(比如
KeyError)?会导致 500,而不是你预设的 403
最隐蔽的问题:用 app.test_client() 写单元测试时,before_request 默认不运行——需手动 push 上下文:with app.app_context(): ... 或使用 client = app.test_client(use_cookies=True) 并确保请求头完整。
真正麻烦的是混合部署场景:比如 Flask 前面挂了 Nginx,真实 IP 被藏在 X-Forwarded-For 里,但你在 before_request 中直接读 request.remote_addr,拿到的永远是 127.0.0.1。这种细节不验证请求头来源,拦截逻辑就形同虚设。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










