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

Posted

技术标签:

【中文标题】如何根据请求的 URL 的域在 Flask 中路由?【英文标题】:How do I route in Flask based on the domain of the requested URL? 【发布时间】:2015-04-17 03:02:06 【问题描述】:

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

根据我读过的here 和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“找不到页面”。我还需要做些什么来使它正常工作吗?链接的SO answer 提到“当您将 host_matching 设置为 true 时需要为所有路由指定主机”,但我不确定这意味着什么或它会是什么样子(我认为这就是我在上面所做的)。

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


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

【问题讨论】:

【参考方案1】:

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

>>> 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')

所以修改后的主机字符串'&lt;prefix&gt;.&lt;project&gt;-elasticbeanstalk.com' 匹配,并将前缀和项目传递到视图中。也许只是当主机字符串不包含端口号时,您试图匹配端口号?

【讨论】:

我可以确认(例如通过禁用 host_matchingrequest.url_root 符合预期。例如。我得到“www.mydomain.com”或“www.myproject-elasticbeanstalk.com”。那是等价的吗? 原地修改答案。

以上是关于如何根据请求的 URL 的域在 Flask 中路由?的主要内容,如果未能解决你的问题,请参考以下文章

flask的路由

Django与Flask的对比:路由映射的区别

Flask源码复习之路由

Python中Flask框架的变量和函数

Flask 在 URL 中添加斜杠,没有路由匹配

Flask视图:视图函数,类视图,蓝图使用方法整理