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

主宰稳场 提交于 2019-12-21 06:30:00

问题


I'm trying to implement routing based on the host of the requested URL for a Flask site I'm building.

Based on what I've read here and elsewhere, it seems like this should be possible with something like

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'

but this fails with 404 "page not found". Is there something else I need to do to get this working? The linked SO answer mentions "the need to specify the host for all routes when you set host_matching to true" but I'm not sure what this means or what it would look like (I thought that's what I had been doing above).

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


If it matters, this site is hosted on AWS Elastic Beanstalk.


回答1:


One way of debugging these situations is to just jump into a console and play with the underlying functions:

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

If it didn't match it would raise a NotFound exception.

You can run that command on one line

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

And get a really quick feedback loop about what you are doing wrong. The only thing I can't tell from your code example is what the actual host string looks like... and that's the important part. That's what you need to know and feed into the m.bind call. So if you can tell me what the host string looks like in your particular situation I can definitely debug this for you.

An example host string provided by you was: 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'})

So a modified host string of '<prefix>.<project>-elasticbeanstalk.com' matches that and would pass the prefix and project into the view. Maybe it's simply that you're trying to match on port numbers when the host strings don't include them?



来源:https://stackoverflow.com/questions/28544180/how-do-i-route-in-flask-based-on-the-domain-of-the-requested-url

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!