news 2026/4/27 22:14:31

Flask 的before_request钩子深度详解

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Flask 的before_request钩子深度详解

1. 他是什么

before_request是 Flask 框架里的一个请求钩子(hook)。可以把它想象成一家餐厅的迎宾员——每当有客人走进餐厅(也就是客户端向服务器发来一个请求),迎宾员都会先一步上前,在客人落座点菜(视图函数执行)之前完成一些固定的接待动作。

在 Flask 里,你用@app.before_request装饰一个函数,这个函数就会在每次请求进入路由、执行视图函数之前被自动调用。

2. 他能做什么

因为before_request跑在业务逻辑之前,而且可以访问请求对象request,所以它很适合处理那些每个请求都需要、但又跟具体业务无关的横切关注点。

  • 身份验证:检查用户是否已登录,如果没登录就直接返回登录页面,不再往下走视图函数。

  • 请求日志:记录每一次请求的路径、来源 IP、耗时等。

  • 设置全局变量:把从数据库里查出的用户信息挂载到g对象上,供视图函数后续使用。

  • 请求预处理:强制要求请求使用 HTTPS,或者统一把 POST 表单里的空格 trim 掉。

  • 限流或黑白名单:在请求到达业务层之前就把非法 IP 拦下。

用一个生活例子:小区门卫。before_request就像门卫,所有访客(请求)进小区前,门卫都会做同一套动作——登记、查健康码、询问房号,做完才放行去找具体住户(视图函数)。

3. 怎么使用

用法非常简单,直接在 Flask 应用实例上注册装饰器。

python

from 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_requestprocess_viewprocess_response等多个阶段,并且可以控制请求在整个处理管道中的流转。
Flask 的before_request只相当于process_request这一阶段,并且只能通过返回Responseabort来截断请求,没有 Django 中间件那种“向前调用”的灵活性。但 Flask 的优势是轻量、直观,学习成本和代码侵入性都更低。

与 Flask 的before_first_request对比
before_first_request只在应用启动后第一个请求进来时执行一次,适合做初始化动作(如加载配置、预热缓存)。而before_request每一次请求都会执行,两者作用范围完全不同,不能混用。

与装饰器方式对比
你也可以写一个自定义装饰器,把它加到需要鉴权的视图函数上。这种方式更精确——只对特定路由生效,但需要显式装饰每个函数,容易遗漏。
before_request则是“全局生效”或“蓝图范围生效”,一劳永逸,适合那些所有接口都必须遵守的规则。如果规则只在部分接口适用,优先考虑蓝图级钩子或自定义装饰器,避免全局钩子误伤公开接口。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/24 13:27:03

【回眸】系统读书笔记(四)

目录 前言 复盘:戒网 ——笔记节选2 后记 前言 这绝对是博主开账号以来更新的最快的一个系列,许愿后面不鸽不断更,早日完结。 前几天整理房间的时候看到很早以前的日记本,虽然说是日记本,实际上只断断续续写了几天…

作者头像 李华
网站建设 2026/4/25 22:15:25

ansible的filesystem模块--tmp

filesystem模块分区格式化模块参数解释dev块设备名称(磁盘路径)fstype分区格式resizefs将文系统系统大小增加到磁盘的大小示例代码 - name: 创建xfs文件系统filesystem:fstype: xfsdev: /dev/vdb1

作者头像 李华
网站建设 2026/4/25 8:04:05

小白程序员必备:收藏这份2026年大模型转行学习指南,轻松入门AI新赛道!大模型应用开发,2026程序员如何转行大模型?

2025年AI行业因DeepSeek等大模型技术发展迎来热潮,为程序员提供转行良机。文章分析AI行业现状与趋势,指出技术门槛降低、市场需求旺盛、持续学习机会和高薪回报是转行优势。介绍了模型研发、算法、数据科学等热门岗位及其要求,并提供了系统学…

作者头像 李华
网站建设 2026/4/25 8:11:41

HPE助力2026年冬奥会网络基础设施建设

HPE在确保2026年冬奥会网络连接方面发挥了重要作用,这次部署不仅展示了其自身的技术和服务能力,还整合了收购的Juniper Networks的技术方案,这是首次在大型赛事中同时运用两家公司的技术。Milano Cortina 2026冬奥会覆盖面积超过22,000平方公…

作者头像 李华
网站建设 2026/4/25 3:31:40

【开题答辩全过程】以 基于Java的网吧计费管理系统设计与实现为例,包含答辩的问题和答案

个人简介一名14年经验的资深毕设内行人,语言擅长Java、php、微信小程序、Python、Golang、安卓Android等开发项目包括大数据、深度学习、网站、小程序、安卓、算法。平常会做一些项目定制化开发、代码讲解、答辩教学、文档编写、也懂一些降重方面的技巧。感谢大家的…

作者头像 李华