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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM