python - Flask URL 路由编码问题
问题描述
我在 Flask 中偶然发现了一个奇怪的 Unicode URL 编码问题。
@app.route("/it2/<string:name>")
def render_it2(name=""):
name = _fix_encoding(name)
return _render_file("it2", name)
当name
包含 Unicode 字符时,它们被解码为iso-8859-1
而不是utf-8
.
所以我不得不添加这个_fix_encoding
功能:
def _fix_encoding(string):
return string.encode('iso-8859-1').decode('utf8')
我知道这是肮脏的黑客攻击,这就是为什么我想问 Flask/Werkzeug 大师,我的设置有什么问题?为了使 URL 已经以 UTF-8 解码,我应该改变什么,这样就不需要这种丑陋的重新编码了?
SO上有很多类似的问题/答案,但没有真正有用的回答,例如:
我想应该有一些环境变量,或者一些影响默认 Flask 编码的配置选项。
我在该主机上有以下LANG
/ :LC_*
$ echo $LANG
en_US.UTF-8
$ export | grep LC
declare -x LC_ADDRESS="en_US.UTF-8"
declare -x LC_IDENTIFICATION="en_US.UTF-8"
declare -x LC_MEASUREMENT="en_US.UTF-8"
declare -x LC_MONETARY="en_US.UTF-8"
declare -x LC_NAME="en_US.UTF-8"
declare -x LC_NUMERIC="en_US.UTF-8"
declare -x LC_PAPER="en_US.UTF-8"
declare -x LC_TELEPHONE="en_US.UTF-8"
declare -x LC_TIME="en_US.UTF-8"
什么都没有iso-8859-1
。它从何而来?
解决方案
哪个应用程序/代码/网页会创建嵌入“名称”的 URL?
它位于“名称”已经是 utf-8 编码的地方生成的 HTTP 标头上,但框架的 HTTP 端被告知它是 latin1。您看不到那么多,因为通常 URL 用“%HH”转义 - 其中“HH”是 UTF-8 序列中的字节。如果可以,请更改 URL 的来源以正确转义它们(在 Python 中,对它的调用将是urllib.parse.quote(url)
)。
在此处查看从会话 2.1 到 2.5 的官方 URL 规范:https ://www.rfc-editor.org/rfc/rfc3986#section-2.1
显然没有标准的方法来告诉 HTTP 服务器组件(在 Python 端,WSGI 层和 Flask 本身)这是 URL 本身的文本编码 - 这些组件假设为 Latin-1(AKA iso-8859- 1) 对于您的 utf-8 数据使用的 ASCII 集之外的字节。
最后 - 如果在源代码处引用 URL 不是一种选择,那么您的方法就足够了。您可能会更好地保护您的_fix_encoding
函数免受格式错误的 utf-8 数据的影响,否则您的应用程序将失败。(只需errors="replace"
在调用中添加一个参数即可.decode
)
推荐阅读
- spring-hateoas - 带有 Traverson 客户端和 java.time.Instant 的 Spring HATEOAS
- iis - 具有多个规则的 IIS 反向代理
- mysql - Mysql - 选择具有链接值的行
- python-3.x - 在跳过某些对象时获取列表中的不同部分
- typescript - 实现接口或接口扩展的函数参数
- flutter - 如何在 Windows 上以 HTML 格式查看 Flutter/dart 的覆盖率报告
- angular - Angular 7 可重用的 ng 模板
- postgresql - Grails空标识符错误有时会出现而没有解释
- python - 如果我有重叠工作间隔的开始时间/结束时间,如何计算工作场所的空闲时间?
- javascript - Laravel-farhanwazir laravelgooglemaps