#flask里面的请求扩展相当于django中的中间件
from flask import Flask,request
app = Flask(__name__)
# 执行响应函数之前执行此下面的方法,相当于django中的process_request,这里面不需要参数是因为导入了request,设置为全局参数,若有return则之前返回,后面的before_request一律不执行,包括响应函数也不执行,只会执行after_request
分析源码
#1.点开上面的__call__方法即可看到下面这段代码,发现是执行了wsgi_app方法
def __call__(self, environ, start_response):
"""The WSGI server calls the Flask application object as the
WSGI application. This calls :meth:`wsgi_app` which can be
wrapped to applying middleware."""
return self.wsgi_app(environ, start_response)
#2.再点开wsgi_app方法
def wsgi_app(self, environ, start_response):
ctx = self.request_context(environ)
error = None
try:
try:
ctx.push()
response = self.full_dispatch_request()
except Exception as e:
error = e
response = self.handle_exception(e)
except: # noqa: B001
error = sys.exc_info()[1]
raise
return response(environ, start_response)
finally:
if self.should_ignore_error(error):
error = None
ctx.auto_pop(error)
#3.点开full_dispatch_request()方法
def full_dispatch_request(self):
"""Dispatches the request and on top of that performs request
pre and postprocessing as well as HTTP exception catching and
error handling.
.. versionadded:: 0.7
"""
# 执行请求扩展中的before_first_request方法
self.try_trigger_before_first_request_functions()
try:
request_started.send(self)
rv = self.preprocess_request()
# 由下面的4.2可以得到若返回值是None,则继续执行响应函数
if rv is None:
rv = self.dispatch_request()
except Exception as e:
rv = self.handle_user_exception(e)
return self.finalize_request(rv)
# 源码分析为何before_first_request只执行一次
#4.1点开3中的try_trigger_before_first_request_functions()方法
def try_trigger_before_first_request_functions(self):
"""Called before each request and will ensure that it triggers
the :attr:`before_first_request_funcs` and only exactly once per
application instance (which means process usually).
:internal:
"""
# 若first_request为True则直接返回,若不是则下面for循环并设为True
if self._got_first_request:
return
with self._before_request_lock:
if self._got_first_request:
return
for func in self.before_first_request_funcs:
func()
self._got_first_request = True
# 源码分析为何before_request有返回值其他响应就不执行
#4.2. 点开3中的preprocess_request()方法
def preprocess_request(self):
"""Called before the request is dispatched. Calls
:attr:`url_value_preprocessors` registered with the app and the
current blueprint (if any). Then calls :attr:`before_request_funcs`
registered with the app and the blueprint.
If any :meth:`before_request` handler returns a non-None value, the
value is handled as if it was the return value from the view, and
further request handling is stopped.
"""
bp = _request_ctx_stack.top.request.blueprint
# 获取响应函数执行前的所有函数
funcs = self.url_value_preprocessors.get(None, ())
if bp