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中時,分割結束,根據前綴找到要執行的函數,並做后續的操作。