Flask 路由使用带斜杠的路径
我正在尝试在Flask中使用一个简单的路由和路径转换器:
@api.route('/records/<hostname>/<metric>/<path:context>')
这个方法可以正常工作,但如果URL的“路径”部分前面有一个斜杠,我就会遇到404错误。我明白这个错误的原因,但我不明白的是,文档里或者网上根本没有任何解决办法。我感觉我好像是第一个尝试做这个基本操作的人。
有没有办法让这个功能正常工作,并且能生成有意义的URL?比如说像这样的请求:
http://localhost:5000/api/records/localhost/disks.free//dev/disk0s2
1 个回答
18
PathConverter
URL 转换器 特意不包括开头的斜杠(/),这是故意的,因为大多数路径其实不应该有这个斜杠。
可以查看PathConverter
的源代码:
regex = '[^/].*?'
这个表达式可以匹配任何东西,只要它不以 /
开头。
你不能对路径进行编码;如果你试图把路径中的斜杠(不是用来分隔 URL 的,而是值的一部分)进行 URL 编码成 %2F
,大多数服务器(几乎所有)在把 URL 路径传给 WSGI 服务器之前,都会先解码这个路径。
你需要使用不同的转换器:
import werkzeug
from werkzeug.routing import PathConverter
from packaging import version
# whether or not merge_slashes is available and true
MERGES_SLASHES = version.parse(werkzeug.__version__) >= version.parse("1.0.0")
class EverythingConverter(PathConverter):
regex = '.*?'
app.url_map.converters['everything'] = EverythingConverter
config = {"merge_slashes": False} if MERGES_SLASHES else {}
@api.route('/records/<hostname>/<metric>/<everything:context>', **config)
注意 merge_slashes
这个选项;如果你安装了 Werkzeug 1.0.0 或更新版本,并且保持默认设置,那么多个连续的 /
字符会被合并成一个。
注册转换器必须在 Flask 的 app
对象上进行,而不能在蓝图上进行。