如何根据请求的域 URL 在 Flask 中进行路由?

How do I route in Flask based on the domain of the requested URL?

我正在尝试根据所请求的主机 URL 为我正在构建的 Flask 站点实施路由。

根据我读过的内容 here and elsewhere,这似乎应该可以通过

之类的东西实现
from flask import Flask
application = Flask(__name__)

application.url_map.host_matching = True

@application.route("/", host="<prefix>.mydomain.com:<port>")
def mydomain(prefix='', port=0, **kwargs):
    return 'This is My Domain: with prefix  ' + prefix

@application.route("/", host="<prefix>.<project>elasticbeanstalk.com:<port>")
def test(prefix='', project='', port=0, **kwargs):
    return 'You are reading from EB  ' + project

@application.route("/", host="<host>:<port>")
def catchall(**kwargs):
    return 'This is anything'

但这失败了 404 "page not found"。我还需要做些什么才能让它正常工作吗?链接的 SO answer 提到 "the need to specify the host for all routes when you set host_matching to true" 但我不确定这意味着什么或它看起来像什么(我认为这就是我在上面所做的)。

如何根据请求的域在 Flask 中路由 URL?


如果重要,此站点托管在 AWS Elastic Beanstalk 上。

调试这些情况的一种方法是跳入控制台并使用底层函数:

>>> from werkzeug.routing import Map, Rule
>>> m = Map([Rule('/', endpoint='endpoint', host='<host>.example.com:<port>')], host_matching=True)
>>> c = m.bind('open.example.com:888')
>>> c.match('/')
('endpoint', {'host': u'open', 'port': u'888'})

如果不匹配,将引发 NotFound 异常。

您可以 运行 在一行中执行该命令

>>> Map([Rule('/', endpoint='endpoint', host='<host>.example.com:<port>')], host_matching=True).bind('open.example.com:888').match('/')

并获得关于您做错了什么的真正快速反馈循环。从您的代码示例中我唯一无法分辨的是实际主机字符串的样子……这是重要的部分。这就是您需要了解并输入 m.bind 调用的内容。因此,如果您能告诉我在您的特定情况下主机字符串是什么样的,我绝对可以为您调试它。

您提供的示例主机字符串是:www.myproject-elasticbeanstalk.com.

>>> Map([Rule('/', endpoint='endpoint', host='<prefix>.<project>-elasticbeanstalk.com')], host_matching=True).bind('www.myproject-elasticbeanstalk.com').match('/')
('endpoint', {'prefix': u'www', 'project': u'myproject'})

因此,修改后的 '<prefix>.<project>-elasticbeanstalk.com' 主机字符串与其匹配,并将前缀和项目传递到视图中。也许只是您在主机字符串不包含端口号时尝试匹配端口号?