统一码¶
即使HTTP标准不支持Unicode,Werkzeug也在内部使用字符串,只要假定文本数据是文本数据。基本上,所有传入的数据都是从字符集(默认为UTF-8)解码的,这样就不会直接处理字节。传出数据被编码到目标字符集中。
python中的unicode¶
假设你有德语变音变音 ö
. 在ASCII中,不能表示该字符,但在 latin-1
和 utf-8
可以表示字符集,但编码时它们看起来不同:
>>> "ö".encode("latin1")
b'\xf6'
>>> "ö".encode("utf-8")
b'\xc3\xb6'
安 ö
根据编码的不同看起来不同,这使得它很难作为字节使用。相反,Python将字符串视为Unicode文本并存储信息 LATIN SMALL LETTER O WITH DIAERESIS
而不是 ö
以特定的编码。包含1个字符的字符串的长度将为1,其中字节的长度可能是其他值。
HTTP中的Unicode¶
然而,HTTP规范是在ASCII字节是表示数据的常用方式的时代编写的。为了在现代网络中解决这个问题,Werkzeug会自动解码和编码传入和传出的数据。从浏览器发送到web应用程序的数据从UTF-8字节解码为字符串。从应用程序发送回浏览器的数据被编码回UTF-8。
错误处理¶
执行内部编码或解码的函数接受 errors
传递给的关键字参数 str.decode()
和 str.encode()
. 默认值为 'replace'
这样就很容易发现错误。将其设置为可能有用 'strict'
以便捕捉错误并向客户端报告错误数据。
请求和响应对象¶
在大多数情况下,您应该坚持使用Werkzeug的默认编码UTF-8。如果你有一个特定的原因,你可以子类 wrappers.Request
和 wrappers.Response
更改编码和错误处理。
from werkzeug.wrappers.request import Request
from werkzeug.wrappers.response import Response
class Latin1Request(Request):
charset = "latin1"
encoding_errors = "strict"
class Latin1Response(Response):
charset = "latin1"
只能为请求更改错误处理。在对响应中的字节进行编码时,Werkzeug总是会引发错误。您有责任不创建目标字符集中不存在的数据。这不是UTF-8的问题。
文件系统¶
Changelog
在 0.11 版更改.
针对Werkzeug的一些错误报告显示 sys.getfilesystemencoding()
在传统的UNIX系统下无法信任。这通常是由于系统配置错误而导致的 LANG
类似的环境变量没有设置。在这种情况下,Python默认使用ASCII作为文件系统编码,这是一个非常保守的默认值,通常是错误的,并且会导致比它避免的更多的问题。
如果Werkzeug检测到它在配置错误的环境中运行,它将假定文件系统编码是 UTF-8
并发出警告。