Add a prefix to all Flask routes

后端 未结 10 837
你的背包
你的背包 2020-11-22 09:40

I have a prefix that I want to add to every route. Right now I add a constant to the route at every definition. Is there a way to do this automatically?

PR         


        
10条回答
  •  花落未央
    2020-11-22 10:33

    You should note that the APPLICATION_ROOT is NOT for this purpose.

    All you have to do is to write a middleware to make the following changes:

    1. modify PATH_INFO to handle the prefixed url.
    2. modify SCRIPT_NAME to generate the prefixed url.

    Like this:

    class PrefixMiddleware(object):
    
        def __init__(self, app, prefix=''):
            self.app = app
            self.prefix = prefix
    
        def __call__(self, environ, start_response):
    
            if environ['PATH_INFO'].startswith(self.prefix):
                environ['PATH_INFO'] = environ['PATH_INFO'][len(self.prefix):]
                environ['SCRIPT_NAME'] = self.prefix
                return self.app(environ, start_response)
            else:
                start_response('404', [('Content-Type', 'text/plain')])
                return ["This url does not belong to the app.".encode()]
    

    Wrap your app with the middleware, like this:

    from flask import Flask, url_for
    
    app = Flask(__name__)
    app.debug = True
    app.wsgi_app = PrefixMiddleware(app.wsgi_app, prefix='/foo')
    
    
    @app.route('/bar')
    def bar():
        return "The URL for this page is {}".format(url_for('bar'))
    
    
    if __name__ == '__main__':
        app.run('0.0.0.0', 9010)
    

    Visit http://localhost:9010/foo/bar,

    You will get the right result: The URL for this page is /foo/bar

    And don't forget to set the cookie domain if you need to.

    This solution is given by Larivact's gist. The APPLICATION_ROOT is not for this job, although it looks like to be. It's really confusing.

提交回复
热议问题