Python 尾随斜杠在 Flask 路径规则中触发 404
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/33241050/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Trailing slash triggers 404 in Flask path rule
提问by Jesvin Jose
I want to redirect any path under /users
to a static app. The following view should capture these paths and serve the appropriate file (it just prints the path for this example). This works for /users
, /users/604511
, and /users/604511/action
. Why does the path /users/
cause a 404 error?
我想将任何路径重定向/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
采纳答案by davidism
Your /users
route is missing a trailing slash, which Werkzeug interprets as an explicit rule to not match a trailing slash. Either add the trailing slash, and Werkzeug will redirect if the url doesn't have it, or set strict_slashes=False
on the route and Werkzeug will match the rule with or without the slash.
您的/users
路线缺少尾部斜杠,Werkzeug 将其解释为不匹配尾部斜杠的显式规则。添加尾部斜杠,如果 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
You can also set strict_slashes
for all URLs.
您还可strict_slashes
以为所有 URL设置。
app.url_map.strict_slashes = False
However, you should avoid disabling strict slashes in most cases. The docs explain why:
但是,在大多数情况下,您应该避免禁用严格的斜线。文档解释了原因:
This behavior allows relative URLs to continue working even if the trailing slash is omitted, consistent with how Apache and other servers work. Also, the URLs will stay unique, which helps search engines avoid indexing the same page twice.
即使省略了尾部斜杠,此行为也允许相对 URL 继续工作,这与 Apache 和其他服务器的工作方式一致。此外,URL 将保持唯一,这有助于搜索引擎避免将同一页面索引两次。
回答by Dauros
It's because of Werkzeug's consistency with other HTTP servers. Have a look at Flask's Quickstart documentation. The relevant paragraph:
这是因为 Werkzeug 与其他 HTTP 服务器的一致性。查看 Flask 的快速入门文档。相关段落:
Unique URLs / Redirection Behavior
Flask's URL rules are based on Werkzeug's routing module. The idea behind that module is to ensure beautiful and unique URLs based on precedents laid down by Apache and earlier HTTP servers.
Take these two rules:
@app.route('/projects/') def projects(): return 'The project page' @app.route('/about') def about(): return 'The about page'
Though they look rather similar, they differ in their use of the trailing slash in the URL definition. In the first case, the canonical URL for the projects endpoint has a trailing slash. In that sense, it is similar to a folder on a file system. Accessing it without a trailing slash will cause Flask to redirect to the canonical URL with the trailing slash.
In the second case, however, the URL is defined without a trailing slash, rather like the pathname of a file on UNIX-like systems. Accessing the URL with a trailing slash will produce a 404 “Not Found” error.
This behavior allows relative URLs to continue working even if the trailing slash is omitted, consistent with how Apache and other servers work. Also, the URLs will stay unique, which helps search engines avoid indexing the same page twice.
唯一 URL/重定向行为
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 将保持唯一,这有助于搜索引擎避免将同一页面索引两次。
So just add /users/
as well to the routing.
因此,只需将其添加/users/
到路由中即可。
回答by Nick Woodhams
To disable strict slashes GLOBALLY; set url_map.strict_slashes = False
like so:
全局禁用严格斜线;url_map.strict_slashes = False
像这样设置:
app = Flask(__name__)
app.url_map.strict_slashes = False
This way you do not have to use strict_slashes=False
for each view.
这样您就不必strict_slashes=False
为每个视图使用。
Then you just define the route without a trailing slash like so:
然后,您只需定义不带斜杠的路线,如下所示:
bp = Blueprint('api', __name__, url_prefix='/api')
@bp.route('/my-route', methods=['POST'])
Then /my-route
and /my-route/
both work identically.
然后/my-route
和/my-route/
两者的工作方式相同。