# Flask 视图请求钩子函数



### 请求钩子

在客户端和服务器交互的过程中，有些准备工作或扫尾工作需要处理，比如：

* 在请求开始时，建立数据库连接；
* 在请求开始时，根据需求进行权限校验；
* 在请求结束时，指定数据的交互格式；

为了让每个视图函数避免编写重复功能的代码，Flask提供了通用设置的功能，即请求钩子。

请求钩子是通过装饰器的形式实现，Flask支持如下四种请求钩子：

* before\_first\_request
* before\_request
* after\_request
* teardown\_request：

```python
from flask import Flask, abort


app = Flask(__name__)


@app.before_first_request
def before_first_request():
    """
    这个钩子会在项目启动后第一次被用户访问时执行
    可以编写一些初始化项目的代码，例如，数据库初始化，加载一些可以延后引入的全局配置
    """
    print("----before_first_request----")
    print("系统初始化的时候,执行这个钩子方法")
    print("会在接收到第一个客户端请求时,执行这里的代码")
    print("执行顺序一")


@app.before_request
def before_request():
    """
    这个钩子会在每次客户端访问视图的时候执行
    # 可以在请求之前进行用户的身份识别，以及对于本次访问的用户权限等进行判断。..
    """
    print("----before_request----")
    print("每一次接收到客户端请求时,执行这个钩子方法")
    print("一般可以用来判断权限,或者转换路由参数或者预处理客户端请求的数据")
    print("执行顺序二")


@app.after_request
def after_request(response):
    print("----after_request----")
    print("在处理请求以后,执行这个钩子方法")
    print("一般可以用于记录会员/管理员的操作历史,浏览历史,清理收尾的工作")
    response.headers["Content-Type"] = "application/json"
    response.headers["Company"] = "python oldboy..."
    # 必须返回response参数
    print("执行顺序四")
    print(response)     # <Response 2 bytes [200 OK]>
    return response


@app.teardown_request
def teardown_request(exc):
    print("----teardown_request----")
    print("在每一次请求以后,执行这个钩子方法")
    print("如果有异常错误,则会传递错误异常对象到当前方法的参数中")
    # 在项目关闭了DEBUG模式以后，则异常信息就会被传递到exc中，我们可以记录异常信息到日志文件中
    print(exc)


@app.route('/')
def qwq():
    print('执行顺序三')
    abort(400)          # 主动抛出HTTP异常   400 – HTTP的错误状态码 只能是异常状态代码的 HTTPException 或者 指定响应
    return 'ok'


if __name__ == '__main__':
    app.run(debug=True)
```
