您正在混合 Unicode 和字节串。
>>> msg = u'abc' # Unicode string
>>> message_body = b'\xc5' # bytestring
>>> msg += message_body
Traceback (most recent call last):
File "<input>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc5 in position 0: ordinal \
not in range(128)
要修复它,请确保self.headers
内容被正确编码,即所有键、值headers
应该是字节串:
self.headers = dict((k.encode('ascii') if isinstance(k, unicode) else k,
v.encode('ascii') if isinstance(v, unicode) else v)
for k,v in self.headers.items())
注意:标头的字符编码与正文的字符编码无关,即 xml 文本可以独立编码(从 http 消息的角度来看,它只是一个八位字节流)。
同样适用于self.url
——如果它有unicode
类型;将其转换为字节串(使用“ascii”字符编码)。
HTTP 消息由起始行、“标头”、空行和可能的消息正文组成 so self.headers
用于标题,self.url
用于起始行(http 方法在此处),并且可能用于Host
http 标头(如果客户端是 http/1.1),XML 文本转到消息正文(作为二进制 blob)。
使用 ASCII 编码始终是安全的self.url
(IDNA 可用于非 ASCII 域名 — 结果也是 ASCII)。
这是什么rfc 7230 关于 http 的说明headers字符编码:
从历史上看,HTTP 允许字段内容包含文本
ISO-8859-1 字符集 [ISO-8859-1],仅支持其他字符集
通过使用 [RFC2047] 编码。实际上,大多数 HTTP 标头
字段值仅使用 US-ASCII 字符集 [USASCII] 的子集。
新定义的标头字段应该将其字段值限制为
US-ASCII 八位字节。接收者应该处理字段中的其他八位字节
内容(obs-text)作为不透明数据。
要将 XML 转换为字节串,请参阅application/xml编码注意事项:
建议所有 XML MIME 实体使用不带 BOM 的 UTF-8。