1

我需要做的最好作为例子来描述。以前,我有以下代码:

content = u'<?xml version="1.0" encoding="windows-1251"?>\n' + ... #
with open(file_name, 'w') as f:
     f.write(content.encode('cp1251'))
     f.close;

现在我想修改我的整个应用程序的架构,并通过 JSON 将应该是文件内容的字符串发送给客户端,并通过 javascript 生成文件。

所以,现在我的代码看起来像这样:

response_data = {}
response_data['file_content'] = content.encode('cp1251')
response_data['file_name'] = file_name    
return JsonResponse({'content':json.dumps(response_data,  ensure_ascii=False)}) # error generated

问题是我得到UnicodeDecodeError: 'ascii' codec can't decode byte 0xd4 in position 53: ordinal not in range(128)

我也以这种方式尝试了第二个选项:

response_data = {}
response_data['file_content'] = content
response_data['file_name'] = file_name    
return JsonResponse({'content':json.dumps(response_data,  ensure_ascii=False).encode('utf8')}) # error generated

然后,在客户端,我尝试将 utf8 转换为 windows-1251。

 $.post ('/my_url/', data, function(response) {
        var file_content = JSON.parse(response.content).file_content;
        file_content = UnicodeToWin1251(file_content);

...但是...我得到扭曲的符号。我知道我在这里做了一些非常错误的事情,并且可能会在编码方面搞砸,但我仍然一整天都无法解决这个问题。有人可以提示我的错误在哪里吗?

4

1 回答 1

2

XML 和 JSON 都包含Unicode 文本数据。XML 声明只是告诉您的 XML 解析器如何解码该数据的 XML 序列化。您手动编写了序列化,因此为了匹配 XML 标头,您必须编码为 CP-1251。

JSON 标准规定所有 JSON 都应以 UTF-8、UTF-16 或 UTF-32 编码,其中以 UTF-8 为标准;同样,这只是序列化的编码。

将您的数据保留为Unicode,然后使用库将该数据编码为 JSON json;该库负责确保您获得 UTF-8 数据(在 Python 2 中),或者为您提供稍后可以编码为 UTF-8 的 Unicode 文本(Python 3)。然后,您的 Javascript 代码将再次解码 JSON,此时您再次拥有Unicode 文本

response_data = {}
response_data['file_content'] = content
response_data['file_name'] = file_name    
return JsonResponse({'content':json.dumps(response_data,  ensure_ascii=False)})

此处无需通过 JSON 发送二进制数据,您正在发送文本。如果您的 Javascript 代码随后生成该文件,则它负责编码为 CP-1251,而不是您的 Python 代码。

如果必须将二进制数据放入 JSON 有效负载中,则需要将该有效负载编码为某种形式的文本。二进制数据(CP-1251 编码的文本是二进制数据)可以在文本中编码为 Base-64:

import base64

response_data = {}
response_data['file_content'] = base64.encodestring(content.encode('cp1251')).decode('ascii')
response_data['file_name'] = file_name    
return JsonResponse({'content':json.dumps(response_data,  ensure_ascii=False)})

Base64 数据被编码为仅包含 ASCII 数据的字节串,因此将其解码为 JSON 库的 ASCII,它期望文本是 Unicode 文本。

现在您正在向 Javascript 客户端发送以 Base64 文本编码封装的二进制数据,如果您需要二进制有效负载,该客户端现在必须对 Base64 进行解码。

于 2016-12-27T17:37:00.287 回答