flask 中的before_request 与 after_request

本文介绍了Flask框架中before_request和after_request装饰器的使用方法。before_request可用于请求前的预处理,如IP地址过滤;after_request则适用于对响应结果进行后处理,例如数据压缩。这两种机制为开发者提供了灵活的功能扩展方式。

使用before_request 和 after_request的方法都非常简单,使用 @app.before_request  或者@app.after_request  修饰期望在请求前或请求后执行的函数即可

    示例:

 

@app.before_request
def before_request():
    if not m_ip_range.is_ip_strict():
        return
    ranges = m_ip_range.get_range()
    ip_int = utils.ip_to_int(request.remote_addr)
    yes = False
    for item in ranges:
        if item['is_used']==0:
            continue
        if ip_int >= item['ip_start'] and ip_int <= item['ip_end']:
            yes = True
            break
    if not yes:
        abort(400)

    

 

    before_request()函数被修饰以后,每一次请求到来后,都会先执行它,如果没问题即没有执行到abort(400),那么就会进入到正常的被app.route修饰的函数中进行响应,如果有多个函数被app.before_request修饰了,那么这些函数会被依次执行。

    你很关心这个before_request装饰器有什么用,其实它的用处非常大,比如我们希望能对ip地址进行过滤,虽然你可以使用nginx,但我们也可以使用before_request来做,使用nginx,我们不得不手动的进行设置,但如果是用flask自身的before_request机制,我们可以在程序判断出某个ip有恶意访问行为后将其加入到缓存当中(redis),每次请求到来时,由before_request来判断这个ip是不是合法的。

 

    被app.after_request修饰过的函数会在请求得到相应后返回给用户前被调用,也就是说,这个时候,请求已经被app.route装饰的函数响应过了,已经形成了response,我们在这个时候做一些操作,flask有一个插件叫 flask-compress,是对响应结果进行压缩的,它就是用after_request的这个机制,在response返回前对数据进行了压缩,如果你有别的想要操作的事情,同样可以使用after_request来完成。

关注公众号,更多python干货分享

<think>嗯,用户之前问过Flask中间件有哪些,我介绍了Werkzeug内置的、第三方中间件、自定义中间件,以及Flask的请求钩子比如before_requestafter_request。现在用户的新问题是:“除了before_requestbefore_request还有哪些”,这里可能用户有笔误,重复了before_request,应该是指除了before_requestafter_request之外还有哪些钩子函数。 首先需要确认用户的问题是否有误。根据之前的对话,用户可能想了解Flask中除了before_requestafter_request之外的其他请求钩子。Flask确实提供了多个装饰器来注册钩子函数,用于不同阶段的处理。 接下来需要列出其他钩子函数,比如before_first_request、teardown_request、teardown_appcontext等,并解释它们的用途和执行顺序。同时,需要给出示例代码,说明每个钩子的使用场景,比如初始化操作、资源清理等。 另外,用户可能对钩子函数的执行顺序不太清楚,需要简要说明它们何时被调用,比如before_first_request只在第一次请求前执行,teardown_request在每次请求结束后执行,无论是否有异常发生。 还需要注意是否需要区分应用上下文和请求上下文的钩子,比如teardown_appcontext和teardown_request的区别,以及after_this_request这种在特定请求之后触发的钩子。 最后要确保回答结构清晰,分点列出每个钩子,给出示例和说明,帮助用户全面了解Flask的钩子函数,避免遗漏重要信息。同时,提醒用户在实际开发中如何合理使用这些钩子,比如资源管理和错误处理的最佳实践。</think>在Flask框架中,除了`@app.before_request`和`@app.after_request`之外,还有以下重要的请求钩子函数(按执行顺序排列): --- ### **1. before_first_request** - **作用**:应用启动后处理第一个请求之前执行 - **场景**:初始化全局资源(数据库连接池、缓存预热等) ```python @app.before_first_request def init_resources(): print("首次请求初始化中...") redis_client.ping() # 测试Redis连接 ``` --- ### **2. teardown_request** - **特点**:无论请求是否成功都会执行 - **场景**:请求级别的资源清理(关闭数据库连接、释放文件句柄等) ```python @app.teardown_request def cleanup(exc): db.session.remove() # 每次请求后关闭SQLAlchemy会话 if exc: print(f"请求异常: {exc}") ``` --- ### **3. teardown_appcontext** - **特点**:应用上下文结束时触发 - **场景**:应用级别的资源回收(关闭长期连接) ```python @app.teardown_appcontext def shutdown_session(exception=None): storage.release() # 释放全局存储资源 ``` --- ### **4. after_this_request** - **特点**:在当前请求处理函数内注册后置操作 - **场景**:动态添加响应头/Cookie ```python @app.route('/download') def download_file(): @after_this_request def add_header(response): response.headers['X-Accel-Redirect'] = '/protected/file.zip' return response return '触发下载' ``` --- ### **5. errorhandler** - **特殊钩子**:捕获指定HTTP状态码或异常 - **场景**:统一错误页面/自定义异常处理 ```python @app.errorhandler(404) def page_not_found(error): return render_template('404.html'), 404 @app.errorhandler(DatabaseError) def handle_db_error(error): db.session.rollback() return "数据库操作失败", 500 ``` --- ### **执行顺序图示** ``` 客户端请求 → before_first_request(仅首次) → before_request → 路由处理函数 → after_request → teardown_request → teardown_appcontext(应用上下文销毁时) ``` --- ### **使用建议** 1. **资源管理**:优先使用`teardown_request`而非`after_request`进行资源释放 2. **异常处理**:`teardown`系列钩子即使发生异常也会执行 3. **上下文感知**:`after_this_request`只在当前请求生效 4. **性能影响**:避免在钩子中执行耗时操作,特别是全局钩子 示例:完整请求生命周期 ```python @app.before_request def start_timer(): g.start = time.time() @app.after_request def log_request(response): duration = time.time() - g.start app.logger.info(f"{request.path} 耗时 {duration:.2f}s") return response ```
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

酷python

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值