1. 他是什么before_request是 Flask 框架里的一个请求钩子hook。可以把它想象成一家餐厅的迎宾员——每当有客人走进餐厅也就是客户端向服务器发来一个请求迎宾员都会先一步上前在客人落座点菜视图函数执行之前完成一些固定的接待动作。在 Flask 里你用app.before_request装饰一个函数这个函数就会在每次请求进入路由、执行视图函数之前被自动调用。2. 他能做什么因为before_request跑在业务逻辑之前而且可以访问请求对象request所以它很适合处理那些每个请求都需要、但又跟具体业务无关的横切关注点。身份验证检查用户是否已登录如果没登录就直接返回登录页面不再往下走视图函数。请求日志记录每一次请求的路径、来源 IP、耗时等。设置全局变量把从数据库里查出的用户信息挂载到g对象上供视图函数后续使用。请求预处理强制要求请求使用 HTTPS或者统一把 POST 表单里的空格 trim 掉。限流或黑白名单在请求到达业务层之前就把非法 IP 拦下。用一个生活例子小区门卫。before_request就像门卫所有访客请求进小区前门卫都会做同一套动作——登记、查健康码、询问房号做完才放行去找具体住户视图函数。3. 怎么使用用法非常简单直接在 Flask 应用实例上注册装饰器。pythonfrom flask import Flask, g, request, abort app Flask(__name__) app.before_request def load_logged_in_user(): # 假设 token 放在请求头里 token request.headers.get(Authorization) if token: user verify_token(token) # 自定义的 token 校验函数 g.user user # 挂载到 g 对象 else: g.user None app.before_request def reject_suspicious_ips(): blacklist [192.168.1.100, 10.0.0.5] if request.remote_addr in blacklist: abort(403) # 直接返回禁止访问不会进视图如果有多个before_request函数它们会按照注册顺序从上往下执行。任何一个函数返回了Response对象或者调用了abort、抛异常请求流程就会被中断后面的before_request和视图函数都不会执行。4. 最佳实践只放轻量逻辑before_request会增加每个请求的额外耗时。不要把重计算、长时间 I/O 操作放进来否则整个应用的响应时间都会被拖慢。身份校验查缓存日志写入用异步或本地队列不要直接同步写数据库。区分全局与蓝图如果只有一部分路由需要某个前置逻辑比如只有管理后台需要鉴权应该使用蓝图的before_request而不是全局的app.before_request。蓝图级别的钩子只对该蓝图下的路由生效避免污染公共接口。谨慎修改request对象request在 Flask 里是只读的不要试图直接赋值request.method GET。如果需要修改请求数据例如统一给 JSON body 加字段可以考虑在钩子里重新封装一个对象挂到g上而不是篡改原请求。善用g对象before_request里计算好的数据如当前用户、请求开始时间戳可以存到g里后面的视图函数或after_request都能直接取用省去重复查询。异常处理before_request里抛出的异常会走全局异常处理器所以请确保app.errorhandler能覆盖到钩子里可能抛出的异常类型例如abort(403)。5. 和同类技术对比与after_request对比before_request在请求开始前执行after_request在视图函数执行完后、响应发给客户端前执行。一个负责进场预处理一个负责出场包装分工明确。与 Django 中间件对比Django 的中间件是一个更重、更完善的体系分为process_request、process_view、process_response等多个阶段并且可以控制请求在整个处理管道中的流转。Flask 的before_request只相当于process_request这一阶段并且只能通过返回Response或abort来截断请求没有 Django 中间件那种“向前调用”的灵活性。但 Flask 的优势是轻量、直观学习成本和代码侵入性都更低。与 Flask 的before_first_request对比before_first_request只在应用启动后第一个请求进来时执行一次适合做初始化动作如加载配置、预热缓存。而before_request是每一次请求都会执行两者作用范围完全不同不能混用。与装饰器方式对比你也可以写一个自定义装饰器把它加到需要鉴权的视图函数上。这种方式更精确——只对特定路由生效但需要显式装饰每个函数容易遗漏。before_request则是“全局生效”或“蓝图范围生效”一劳永逸适合那些所有接口都必须遵守的规则。如果规则只在部分接口适用优先考虑蓝图级钩子或自定义装饰器避免全局钩子误伤公开接口。