赞
踩
接着此前Flask源码剖析系列,这次来看看Flask是怎么样生成响应的。
Flask会将视图函数返回的值作为Response返回给客户端,这一步对Flask框架使用者而言是透明的,最基本的用法如下:
@app.route('/')
def hello():
return 'Hello, 二两!', 200, {
'Content-Type': 'application/json'}
在hello方法中,返回了了http状态、body以及header等,该方法返回的其实是一个tuple,这里究竟发送了什么?才让一个tuple变为一个Response。
在本系列第一篇文章「Flask源码剖析(一):Flask启动流程」中提到了full_dispatch_request()方法,该方法会找到当前请求路由对应的方法,调用该方法,获得返回(即response),如果请求路由不存在,则进行错误处理,返回500错误。
在full_dispatch_request()方法中会调用finalize_request()方法对返回数据进行处理,response对象的构建就在该方法中实现,该方法源码如下。
# flask/app.py/Flask
def finalize_request(self, rv, from_error_handler=False):
response = self.make_response(rv)
try:
response = self.process_response(response)
request_finished.send(self, response=response)
except Exception:
if not from_error_handler:
raise
self.logger.exception(
"Request finalizing failed with an error while handling an error"
)
return response
finalize_request()方法调用make_response()方法将视图函数返回的tuple转为了response对象,随后再通过process_response()方法进行了相关的hooks处理,具体而言就是执行ctx._after_request_functions
变量中存放的方法。
这里重点看一下make_response()方法,其源码如下。
def make_response(self, rv):
status = headers = None
if isinstance(rv, tuple):
len_rv = len(rv)
if len_rv == 3:
rv, status, headers = rv
elif len_rv == 2:
if isinstance(rv[1], (Headers, dict, tuple, list)):
rv,<
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。