Trailing slash in Flask route
以下面两条路线为例。
1 2 3 4 5 6 7 8 9
| app = Flask(__name__)
@app.route("/somewhere")
def no_trailing_slash():
#case one
@app.route("/someplace/")
def with_trailing_slash():
#case two |
根据文件,理解如下:
我想看到的行为是案例二行为的"逆"。例如,"/someplace/"将转向"/someplace"而不是相反的方向。有没有一种方法可以定义一个路线来采取这种行为?
据我所知,strict_slashes=False可以在路径上设置,以有效地获得与案例1中案例2相同的行为,但我想做的是获得重定向行为,使其始终重定向到URL而不带尾随斜杠。
我想到的一个解决方案是使用404的错误处理程序,类似于这样。(不确定这是否可行)
1 2 3 4 5
| @app.errorhandler(404)
def not_found(e):
if request.path.endswith("/") and request.path[:-1] in all_endpoints:
return redirect(request.path[:-1]), 302
return render_template("404.html"), 404 |
号
但我想知道是否有更好的解决方案,比如某种应用程序配置的下降,类似于我可以在全球应用的strict_slashes=False。可能是蓝图或URL规则?
- 单独实施,是否将/somplace/重定向到/someplace?
- 我注意到的是,当烧瓶配置中有DEBUG=True时,尾随空格不会被重定向,但当DEBUG=False时,尾随空格会被重定向。
- @可能有用,但管理起来有点痛苦的灰尘。我还有其他一些想法涉及到使用错误处理程序,如果存在无斜杠端点,它将返回重定向。也可以使用某种蓝图。但我已经为其他事情使用了404错误处理程序(它可以被移植进来,但我宁愿不这样做),我不确定是否可以用蓝图来实现。理想的解决方案是像全局URL规则一样插入。
- @科杜鲁,这是一个有趣的观察。我将不得不看一看这个,尽管我不认为我会在生产中使用调试标志,原因很明显。我通常使用龙卷风或GEVENT展开烧瓶。即使我设置了app.debug = True,它似乎也不会接受gevent-wsgi环境。我确信有一种方法可以解决这个问题,但这是另一个问题,正如所解释的,对于生产环境来说,可能不是这个问题的适用解决方案。
您使用strict_slashes进行了正确的跟踪,您可以在flask应用程序上进行配置。这将为创建的每个路由将strict_slashes标志设置为False。
1 2
| app = Flask('my_app')
app.url_map.strict_slashes = False |
然后您可以使用before_request检测跟踪/的重定向。使用before_request将允许您不需要将特殊逻辑单独应用于每个路由。
1 2 3 4 5 6 7
| @app.before_request
def clear_trailing():
from flask import redirect, request
rp = request.path
if rp != '/' and rp.endswith('/'):
return redirect(rp[:-1]) |
号
- 当然,我已经搞清楚了。但是,这将重定向到带有尾随斜杠的URL。对非尾随斜杠的请求将是302重定向。我希望尾部斜杠重定向到非尾部斜杠URL。
- @Sytech查看我的更新
- 看起来很有趣。这可能适用于解决方案。如果我采用这种方法,我可能会首先检查无斜杠路径是否存在,然后再重定向到那里,以避免重定向到最终将是404的URL。但是的,这看起来不错。我不确定每次为每条路线注册要运行的函数时的感觉。我将此与使用404错误处理程序进行权衡,该处理程序将检查无斜杠路由是否存在,我认为该路由仅在404发生时运行,并且与此相比可能具有或不具有性能影响。
如果您希望两条路线的处理方式相同,我会这样做:
1 2 3 4 5 6
| app = Flask(__name__)
@app.route("/someplace/")
@app.route("/someplace")
def slash_agnostic():
#code for both routes |
- 如果/someplace是名称空间前缀怎么办?
- @Zobayerhasan,我不明白这个问题。你在描述这样一条路吗:/someplace/someplace?
- 不,我用的是烧瓶。在restplus中,名称空间的使用与蓝图一样。例如,我可以用/someplace前缀注册一个名称空间,然后在我的资源类中,我可以设置@api.route('/')来创建路径/someplace/。
- 我没有使用restplus,所以我不确定类似的东西是否在那里起作用。
- 很好,因为我后来在阅读了更多关于RESTAPI路由设计的内容后发现,一个尾部斜线实际上代表了某种东西。软件工程.stackexchange.com/a/187006/201023