Flask路径规则中的尾部斜杠触发器404


76

我想将任何路径重定向/users到静态应用程序。以下视图应捕获这些路径并提供适当的文件(此示例仅显示路径)。这适用于/users/users/604511/users/604511/action。为什么路径/users/会导致404错误?

@bp.route('/users')
@bp.route('/users/<path:path>')
def serve_client_app(path=None):
    return path

Answers:


132

您的/users路线缺少尾部斜杠,Werkzeug将该尾部斜杠解释为不匹配尾部斜杠的显式规则。添加尾部斜杠,如果URL没有URL,则Werkzeug将重定向,或者strict_slashes=False在路由上设置,并且Werkzeug将匹配带有或不带有斜杠的规则。

@app.route('/users/')
@app.route('/users/<path:path>')
def users(path=None):
    return str(path)

c = app.test_client()
print(c.get('/users'))  # 302 MOVED PERMANENTLY (to /users/)
print(c.get('/users/'))  # 200 OK
print(c.get('/users/test'))  # 200 OK
@app.route('/users', strict_slashes=False)
@app.route('/users/<path:path>')
def users(path=None):
    return str(path)

c = app.test_client()
print(c.get('/users'))  # 200 OK
print(c.get('/users/'))  # 200 OK
print(c.get('/users/test'))  # 200 OK

您还可以设置strict_slashes所有URL。

app.url_map.strict_slashes = False

但是,在大多数情况下,应避免禁用严格的斜杠。该文档解释了原因:

即使省略了斜杠,此行为也允许相对URL继续工作,这与Apache和其他服务器的工作方式一致。而且,URL将保持唯一,这有助于搜索引擎避免对同一页面进行两次索引。


45

全局禁用严格斜杠;设置url_map.strict_slashes = False如下:

app = Flask(__name__)
app.url_map.strict_slashes = False

这样,您不必strict_slashes=False为每个视图使用。

然后,您只需定义路线即可,而无需添加斜杠,如下所示:

bp = Blueprint('api', __name__, url_prefix='/api')
@bp.route('/my-route', methods=['POST'])

然后/my-route/my-route/两者工作相同。


在不为每个视图定义蓝图的情况下,我们将如何对其进行严格的斜线处理?
jchi2241 '18年

@ jchi2241错过了您的评论一年了,对不起。该示例使用蓝图,您在应用程序级别进行配置。
尼克·伍德汉姆斯

15

这是因为Werkzeug与其他HTTP服务器的一致性。看看Flask的快速入门文档。相关段落:

唯一网址/重定向行为

Flask的URL规则基于Werkzeug的路由模块。该模块的思想是根据Apache和更早的HTTP服务器制定的先例确保漂亮且唯一的URL。

遵循以下两个规则:

@app.route('/projects/') 
def projects():
    return 'The project page'

@app.route('/about') 
def about():
    return 'The about page'

尽管它们看起来很相似,但是它们在URL定义中使用斜杠的方式有所不同。在第一种情况下,项目端点的规范URL带有斜杠。从这个意义上讲,它类似于文件系统上的文件夹。访问时不带斜杠将导致Flask重定向到带斜杠的规范URL。

但是,在第二种情况下,URL的定义不带斜杠,就像在类似UNIX的系统上文件的路径名一样。使用斜杠访问URL会产生404“未找到”错误。

即使省略了斜杠,此行为也允许相对URL继续工作,这与Apache和其他服务器的工作方式一致。而且,URL将保持唯一,这有助于搜索引擎避免对同一页面进行两次索引。

因此,只需添加/users/路由。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.