请求-响应循环
注:以下的请求意为Flask收到的请求,不是向别的服务器发送的请求,此时你已经是服务器了!响应同理。
一、上下文
首先我们要有一个概念,请求对象,它封装了客户端发送的HTTP请求
Python中默认为全局变量,为了防止使用混乱,引入上下文概念
可视为一种局部变量
Flask中,上下文分为 请求上下文 与 应用上下文
1.请求上下文(request context)
- request : 请求对象,封装了HTTP请求
- session : 记录请求会话中信息的字典
如:
1 2 3 4 | user = request.args.get('user') # HTTP请求 session['name'] = user.id # 字典的用法 session.get('name') |
request 和 session 在请求结束后就会被重置
注意:request 和 session 是两个变量名!不可变!下同理
2.应用上下文(application context)
- current_app : 当前激活的程序实例
- g : 请求时用作临时储存对象,每次请求后被清空
如:
1 2 | current_app.name g.name='abc' |
二、请求调度
用 app.url_map 检查生成的映射
如查看 test.py 中的生成的映射(在py文件所在文件夹打开Python交互环境):
1 2 3 4 5 6 7 8 9 | PS D:\桌面索引\编程\python\Flask Web开发\源码> python Python 3.8.1 (tags/v3.8.1:1b293b6, Dec 18 2019, 23:11:46) [MSC v.1916 64 bit (AMD64)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> from test import app >>> app.url_map Map([<Rule '/' (HEAD, OPTIONS, GET) -> index>, <Rule '/static/<filename>' (HEAD, OPTIONS, GET) -> static>, <Rule '/user/<id>' (HEAD, OPTIONS, GET) -> text_2>, <Rule '/user/<name>' (HEAD, OPTIONS, GET) -> text_1>]) |
三、请求钩子
时在处理请求之前或之后执行代码
Flask支持以下4种钩子:
- before_first_request:注册一个函数,在处理第一个请求之前运行。
- before_request:注册一个函数,在每次请求之前运行。
- after_request:注册一个函数,如果没有未处理的异常抛出,在每次请求之后运行。
- teardown_request:注册一个函数,即使有未处理的异常抛出,也在每次请求之后运行。
四、响应
1、Flask调用视图函数后,其返回值即为响应的内容
同时还需注意状态码,默认设为200,表示成功处理。若要单独定义,则需把数字代码作为第二个返回值
如:
1 2 3 | @app.route('/') def index(): return '<h1>Bad Request</h1>', 400 |
2、Flask视图函数还可以返回Response对象
make_response()函数可接受参数和视图函数的返回值一样,返回一个Response对象
如:
1 2 3 4 5 6 | from flask import make_response @app.route('/') def index(): response = make_response('<h1>This document carries a cookie!</h1>') response.set_cookie('answer', '42') return response |
3、重定向
该响应没有页面文档,只告诉浏览器一个新地址用以加载新页面。
常用302状态码表示
Flask提供了redirect()辅助函数,以生成这种响应:
1 2 3 4 | from flask import redirect @app.route('/') def index(): return redirect('http://www.baidu.com') # 重定向到百度 |
需要注意的是,这样写会报错:
1 2 3 4 5 6 7 | @app.route('/') def index(): response = make_response(redirect('http://www.baidu.com')) 报错信息: TypeError: The view function did not return a valid response. The function either returned None or ended without a return statement |
原因:漏掉了return response 。。。
同时网上还有人这样写:Flask通过make_response实现重定向
1 2 3 4 5 6 7 8 9 10 11 | @app.route('/') def index(): headers = { 'content-type':'text/plain', 'location':'http://www.baidu.com' } # 使浏览器识别返回内容为字符串而不是html response = make_response("<html></html>",301) # 浏览器接收到301状态码之后,会在headers中寻找location以重定向 response.headers = headers return response |
4、错误处理
由abort函数生成
如:
若URL中动态参数id对应的用户不存在,返回状态码404
1 2 3 4 5 6 | from flask import abort @app.route('/user/<int:id>') def text_2(id): if id != 123 : abort(404) return '<h1>Hello, %s</h1>' % id |