Flask - request、response - 请求、响应
程序员文章站
2022-06-01 22:56:43
...
目录
2-1 基于return方式 生成的response对象 的修改操作
3-1 @before_request - 收到请求前执行绑定函数
3-2 @after_request - 每个请求后执行绑定函数,若请求异常不执行
3-3 @before_first_request - 第一次请求时触发函数执行
3-4 @teardown_request - 每个请求后执行绑定函数,若请求异常照常执行
3-5 @errorhandler - 根据错误状态码自定义返回
3-6 @template_global - 模板的标签使用
3-7 @template_filter - 模板过滤器使用
一、request 请求相关属性
- request.method - 请求的方式
- request.args - get方式提交的数据,即URL内包含的数据信息
- request.args.get('key', )
- request.form - Post方式提交的数据,字典形式存储获取
- request.values - CombinedMultiDict 字典形式存储,内容是
form
和args
。 可以使用values替代form和args。- request.cookies - 请求的cookies,类型是dict
- request.stream - 在可知的mimetype下,如果进来的表单数据无法解码,会没有任何改动的保存到这个·stream·以供使用。很多时候,当请求的数据转换为string时,使用
data
是最好的方式。这个stream只返回数据一次。- request.headers - 请求头,字典形式,结果以list形式返回
- request.data - 包含了请求的数据,并转换为字符串,除非是一个Flask无法处理的mimetype。
- 用户请求路径获取方式(例如 :
http://www.example.com/myapplication/page.html?x=y
)
- request.path - /page.html
- request.full_path
- request.script_root - /myapplication
- request.url - http://www.example.com/myapplication/page.html?x=y
- request.base_url - http://www.example.com/myapplication/page.html
- request.url_root - http://www.example.com/myapplication/
- request.host_url
- request.host
- request.files - MultiDict,带有通过POST或PUT请求上传的文件。
obj = request.files['the_file_name'] obj.save('/var/www/uploads/' + secure_filename(f.filename))
- request.environ - WSGI隐含的环境配置。
- request.is_xhr - 如果请求是发送到一个实际的模块,则该参数返回当前模块的名称。这是弃用的功能,使用
blueprints
替代。- request.blueprint - 蓝图名字
- request.endpoint - endpoint匹配请求,这个与
view_args
相结合,可是用于重构相同或修改URL。当匹配的时候发生异常,会返回None。- request.json - 如果
mimetype
是application/json
,这个参数将会解析JSON数据,如果不是则返回None。
可以使用这个替代get_json()方法。- request.max_content_length - 只读,返回
MAX_CONTENT_LENGTH
的配置键。- request.module - 如果请求是发送到一个实际的模块,则该参数返回当前模块的名称。这是弃用的功能,使用
blueprints
替代。1-1 基于 request 的 ip 获取
Python Flask使用Nginx做代理时如何获取真实IP
Nginx反向代理 + Flask + gunicorn 架构解决获取用户真实ip问题
request.headers.get('REMOTE_ADDR') request.headers.get('HTTP_X_FORWARDED_FOR') request.remote_addr request.environ.get('REMOTE_ADDR') request.environ.get('HTTP_X_FORWARDED_FOR')
二、 response、后台return的数据形式
- return "字符串" - 字符串形式
- return render_template('html模板路径',**{}) - 将数据递交给指定模板
- return redirect('/index.html') - 重定向页面
- return jsonify({'k1':'v1'}) - 返回json数据
2-1 基于return方式 生成的response对象 的修改操作
from flask import make_response,jsonify # 生成response对象,用于往内进行添加操作 - 三种实现方式 # response是flask.wrappers.Response类型 response = make_response("字符串") response = make_response(render_template('index.html')) response = make_response(redirect('/index.html')) response = make_response(jsonify({'k1':'v1'})) # 对response进行cookie操作,删除写入cookie值 response.delete_cookie('key') response.set_cookie('key', 'value') response.headers['X-Something'] = 'A value' return response
三、request 请求扩展
!!注意点总结!!
- 执行流程
- @before_request 包裹函数1,函数2
- 请求的执行
- @after_request 包裹函数2,函数1
- 若 @before_request 或者@after_request 包裹函数内存在return返回值,之后其他被 after_request包裹的函数照常执行。
3-1 @before_request - 收到请求前执行绑定函数
类比django中间件中的process_request,在请求收到之前绑定一个函数做一些事情
# 基于before_request的用户登录认证 @app.before_request def process_request(*args,**kwargs): if request.path == '/login': return None user = session.get('user_info') if user: return None return redirect('/login')
3-2 @after_request - 每个请求后执行绑定函数,若请求异常不执行
类比django中间件中的process_response,每一个请求之后绑定一个函数,如果请求没有异常
@app.after_request def process_response1(response): print('process_response1 执行') return response
3-3 @before_first_request - 第一次请求时触发函数执行
@app.before_first_request def first(): pass
3-4 @teardown_request - 每个请求后执行绑定函数,若请求异常照常执行
@app.teardown_request def ter(e): pass
3-5 @errorhandler - 根据错误状态码自定义返回
路径不存在时404,服务器内部错误500
@app.errorhandler(404) def error_404(arg): return "404错误了"
3-6 @template_global - 模板的标签使用
@app.template_global() def sb(a1, a2): return a1 + a2 #{{sb(1,2)}}
3-7 @template_filter - 模板过滤器使用
@app.template_filter() def db(a1, a2, a3): return a1 + a2 + a3 #{{ 1|db(2,3)}}
四、中间件
4-1 中间件实现方式
from flask import Flask app = Flask(__name__) @app.route('/') def index(): return 'Hello World!' # 模拟中间件 class Md(object): def __init__(self,old_wsgi_app): self.old_wsgi_app = old_wsgi_app def __call__(self, environ, start_response): print('开始之前') ret = self.old_wsgi_app(environ, start_response) print('结束之后') return ret if __name__ == '__main__': # 将原wsgi_app作为参数传入,即替换操作 app.wsgi_app = Md(app.wsgi_app) app.run()
4-2 源码分析
每次执行Flask对象时,本质上是调用了对象的__call__方法。
即,在__call__方法return前执行的逻辑为请求未开始前最开始的部位,return后执行的逻辑为最末尾的执行。
所以中间件的实现方式,重写Flask对象的__call__方法,将前后逻辑包裹在 wsgi_app(environ, start_response) 的执行前后。
五、请求上下文源码分析 - 请求流程解析
程序运行,两个LocalStack()对象,一个里面放request和session,另一个放g和
current_app
'''第一阶段:将ctx(request,session)放到Local对象上''' '''第二阶段:视图函数导入:request/session''' request.method -LocalProxy对象.method,执行getattr方法,getattr(self._get_current_object(), name) -self._get_current_object()返回return self.__local(),self.__local(),在LocakProxy实例化的时候,object.__setattr__(self, '_LocalProxy__local', local),此处local就是:partial(_lookup_req_object, 'request') -def _lookup_req_object(name): top = _request_ctx_stack.top #_request_ctx_stack 就是LocalStack()对象,top方法把ctx取出来 if top is None: raise RuntimeError(_request_ctx_err_msg) return getattr(top, name)#获取ctx中的request或session对象 '''第三阶段:请求处理完毕''' - 获取session并保存到cookie - 将ctx删除
推荐阅读
-
Flask框架 请求与响应 & 模板语法
-
java应用程序向服务器发送request请求,并接受响应
-
drf--请求与响应:Request与Response常用属性、状态码
-
Request、Response 之 Http 请求
-
原生JS实现Ajax跨域请求flask响应内容
-
Flask框架 请求与响应 & 模板语法
-
Flask response响应的具体使用
-
YII Framework学习之request与response用法(基于CHttpRequest响应)_php实例
-
YII Framework学习之request与response用法(基于CHttpRequest响应),yiichttprequest_PHP教程
-
[flask小坑] request.json 无法获取请求body的json数据