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

Posted

技术标签:

【中文标题】Flask 在 URL 中添加斜杠,没有路由匹配【英文标题】:Flask adds trailing slash to URL, no routes match 【发布时间】:2018-08-14 21:27:50 【问题描述】:

根据标题,Apache 2.4 似乎将“/”附加到 URL(根据 request.url)并且 Flask 的路由与它不匹配。

(相关)文件结构

/var/www/wsgi
...
├── dizmo
│   └── __init__.py
├── foo.wsgi
├── hello1.wsgi
└── __pycache__
    └── adapter.cpython-35.pyc

foo.wsgi

import sys
import inspect
sys.path.append('/var/www/wsgi')
from dizmo import app as application

dizmo/__init__.py

from flask import Flask, request
import inspect
import sys

app = Flask(__name__)
app.debug = True
print( "app.config['SERVER_NAME']=".format(app.config['SERVER_NAME']) )
print(": (outside)".format( inspect.currentframe().f_code.co_filename, inspect.currentframe().f_lineno ) )

@app.route('/foo')
@app.route('/foo/')
def tattletale():
    return 'I\'m foo'

@app.errorhandler(404)
def err_handler_404(error):
    return ': no route'.format(request.url), 404

mysite.conf

<VirtualHost *:9000>
    <Directory /var/www/wsgi>
        Require all granted
        DirectorySlash Off
    </Directory>

    WSGIDaemonProcess CDRDB processes=2 threads=15 display-name=%GROUP python-path=/var/www/python-packages
    WSGIProcessGroup CDRDB
    WSGIScriptReloading On
    WSGIScriptAlias /foo /var/www/wsgi/foo.wsgi
    WSGIScriptAlias /hello1 /var/www/wsgi/hello1.wsgi
</VirtualHost>

当它运行时:

curl http://127.0.0.1:9000/foo
http://127.0.0.1:9000/foo/: no route

注意request.url 中的尾部斜杠。

在添加 404 处理程序之前,我在这里和 Reddit 上浏览了两打关于路线的帖子,现在我已经束手无策了。没有 'foo' 目录,所以 DirectorySlash 甚至都不重要。

编辑strict_slashes=False 似乎没有改变任何东西,以及使用单个装饰器,/foo/foo/

编辑 2:显然,Apache 或 mod_wsgi 对路径进行了欺骗,/foo/foo 以某种方式起作用。 Flask 独立服务器按预期工作:

curl http://127.0.0.1:9000/foo/foo  # Apache
I'm foo. route=http://127.0.0.1:9000/foo/foo

curl http://127.0.0.1:5000/foo      # flask run
I'm foo. route=http://127.0.0.1:5000/foo

--

>>> flask.__version__
'0.12.2'
>>> sys.version_info
sys.version_info(major=3, minor=5, micro=2, releaselevel='final', serial=0)
$ apachectl -v
Server version: Apache/2.4.18 (Ubuntu)
Server built:   2017-09-18T15:09:02

【问题讨论】:

尝试将strict_slashes=False 添加到您的路线 Trailing slash triggers 404 in Flask path rule的可能重复 @noslenkwah,我已经尝试过了,但没有运气 - 不知道为什么。 @sytech,我已经看过那个帖子了 你试过/foo/foo 吗?看起来您的 WSGI 脚本别名设置为 /foo - 如果这不起作用,请尝试在没有 Apache/WSGI 的情况下运行您的应用程序,看看它是否按预期工作 【参考方案1】:

您的 WSGIScriptAlias 配置错误。相对于/foo,Apache 正在为您的应用提供服务

要获得您想要的行为,别名应该是根目录,即 I.E。 / 而不是 /foo

【讨论】:

WSGIScriptAlias / /var/... 有效。非常感谢!为了使其与其他脚本别名共存(例如,我的 Apache .conf 中的 /hello)我保留了别名并使用 route('/')route('/tweedledee')route('/tweedledum') 进行装饰。【参考方案2】:

你应该只使用一个装饰器

@app.route('/foo')
@app.route('/foo/')

第二个装饰器也会导致带有最后斜线的重定向。

【讨论】:

两个装饰器都失败了。 解决了这个问题(参见 sytech 的回答),我尝试在有用的装饰器前后添加一个垃圾装饰器。两者都有效。感谢您提示我进行测试。【参考方案3】:

您不需要在第二个装饰器中指定斜线,烧瓶会自动重定向到与您的 url 关联的控制器

我也建议你去掉第二个装饰器...

【讨论】:

以上是关于Flask 在 URL 中添加斜杠,没有路由匹配的主要内容,如果未能解决你的问题,请参考以下文章

如何在 TYPO3 v9 URL 中添加斜杠?

Flask源码复习之路由

flask-路转换器

Flask中路由原理

WCF Rest 4.0 中没有斜杠的简单 URL 路由

flask的路由