flask源码解析之DispatcherMiddleware
DispatcherMiddleware作用
实现多app的应用,完成路由分发的功能
如何使用
from werkzeug.wsgi import DispatcherMiddleware from werkzeug.serving import run_simple from flask import Flask, current_app,request app1 = Flask('app01') app2 = Flask('app02') @app1.route('/index/') def index(): return "app01" @app2.route('/index2/') def index2(): """ 存在的问题: def __call__(self, environ, start_response): # 获取当前请求的URL,script == '/index/' script = environ.get('PATH_INFO', '') path_info = '' # '/' 在 '/index/' 中 while '/' in script: # self.mounts == {'/sec': app2,}, '/' 不在 self.mounts 中 if script in self.mounts: app = self.mounts[script] break script, last_item = script.rsplit('/', 1) path_info = '/%s%s' % (last_item, path_info) else: app = self.mounts.get(script, self.app) original_script_name = environ.get('SCRIPT_NAME', '') environ['SCRIPT_NAME'] = original_script_name + script environ['PATH_INFO'] = path_info # 这里得到的知识不包含前缀的url,那这样不是就丢失了吗 return app(environ, start_response) :return: """ print(request.full_path) # 得到的是 /index2/? 且没有request.path_info return "app2" # http://www.oldboyedu.com/index # http://www.oldboyedu.com/sec/index2 dm = DispatcherMiddleware(app1, { '/sec': app2, }) if __name__ == "__main__": run_simple('localhost', 5000, dm)
注意事项:
在DispatcherMiddleware类的实例参数中,第一个参数不能是一个字典,即第一个参数只能是一个app实例,即没有前缀的。但是后面的APP实例都可以是有前缀的app,存放至字典中
源码分析
请求每次进来执行DispatcherMiddleware的__call__方法,实现分发的原理是:获取本次请求的url,对url进行分割,直到分割出来的部分url(前缀)在保存了分发路由关系字典的self.mounts中时,分割结束,根据前缀找到要执行的函数,并做后续的操作。
感谢您的阅读,如果您觉得阅读本文对您有帮助,请点一下"推荐"按钮,本文欢迎各位转载,但是转载文章之后必须在文章页面中给出作者和原文连接,谢谢。