跳转到主内容
websoft网络软件专家 - 深耕网络技术,打造实用软件!

Python Flask中间件怎么写_利用before_request与全局钩子函数拦截请求与附加日志

Flask的before_request必须在app实例创建后、run()前注册,工厂模式需在create_app内注册,蓝本需用bp.before_request单独挂载;多个钩子按注册顺序执行,任一异常中断后续;应使用app.logger安全记录日志,避免耗时操作;与after_request非自动配对,异常时after_request不执行,需用teardown_request兜底;默认不拦截静态文件和404,需禁用自动静态路由或使用WSGI中间件实现全局拦截。 Flask 的
before_request
怎么注册才生效 它不是装饰器,也不是类方法,必须在 Flask 应用实例创建后、
run()
之前注册,且只对当前应用生效。如果用了工厂模式(
create_app
),得在工厂函数内部注册;如果用了蓝本(Blueprint),
before_request
默认不继承——蓝本自己的钩子得用
bp.before_request
单独挂。 错误写法:
@app.before_request
写在
app = Flask(__name__)
之前 → 报
AttributeError: 'NoneType' object has no attribute 'before_request'
正确位置:紧贴
app = Flask(...)
后,或在
app.config.from_object(...)
之后 多个
before_request
函数会按注册顺序依次执行,任一抛异常都会中断后续钩子和视图函数 怎么在
before_request
里安全地加日志 直接 print 不可靠,尤其部署到 gunicorn/uwsgi 时容易丢行或混入 worker 日志。应该复用 Flask 自带的 logger,它默认绑定到应用名,支持 level 控制和 handler 配置。 用
app.logger.info(f"IP: {request.remote_addr} | Path: {request.path}")
,别手写
logging.getLogger("flask")
避免在钩子里调用耗时操作(比如数据库查询、HTTP 请求),否则所有请求都卡住——日志本身也得轻量,别塞整个
request.headers
或
request.get_data()
想记录请求体?先检查
request.method in ("POST", "PUT")
,再用
request.get_data(cache=True)
,否则重复读会报错
before_request
和
after_request
配合时要注意什么 它们不是成对“自动闭包”的,
after_request
一定执行(除非进程崩溃),但
before_request
中抛异常会导致
after_request
跳过——这时候得靠
teardown_request
补位。 Python 3.14.3 微软官方的 Python 扩展,是 VS Code 安装量最高的扩展(209M+)。集成 IntelliSense(通过 Pylance)、调试(通过 Python Debugger)、代码检查、格式化、重构和单元测试等功能。支持 Jupyter Notebook、虚拟环境管理和多 Python 版本切换。 下载 想确保某段逻辑“无论成功失败都执行”,别依赖
after_request
,改用
@app.teardown_request
after_request
接收一个
response
参数,必须原样返回,哪怕只是
return response
,漏写就 500 修改响应头?用
response.headers["X-Processed"] = "true"
,别直接赋值
response.headers = {...}
,会清空原有头 为什么全局钩子没拦住静态文件或 404 请求
before_request
默认不拦截 Flask 内置的静态文件服务(
/static/xxx
)和 404 等错误响应,因为这些路径在路由匹配前就被短路处理了。想统一处理,得关掉自动静态路由,自己显式注册,或者用 WSGI 中间件(如
Middleware
类)提前介入。 立即学习 “ Python免费学习笔记(深入) ”; 关自动静态:初始化时传
static_folder=None
,然后手动加
@app.route("/static/")
视图 更稳妥的方式:写一个 WSGI 中间件包装
app.wsgi_app
,它在任何 Flask 逻辑之前运行,能真正“全局”拦截 注意:WSGI 中间件里拿不到
request
对象(还没被 Flask 解析),只能读取原始 environ 字典,比如
environ.get("PATH_INFO")
事情说清了就结束。真正难的不是写钩子,是判断哪一层该做什么事——路由层该过滤的别塞进 WSGI,日志该打的别等到响应生成完才攒。

相关文章