【问题标题】:Sending "windows-1251"-encoded string in JSON from python to javascript将 JSON 中的“windows-1251”编码字符串从 python 发送到 javascript
【发布时间】:2017-05-11 23:58:33
【问题描述】:

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

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);

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

【问题讨论】:

    标签: javascript python json cp1251


    【解决方案1】:

    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。

    【讨论】:

    • 我是否理解正确,如果我不提及任何编码,那么内容将是 utf-8 ?
    • @EdgarNavasardyan:Python 2 中的 Python json 库默认编码为 UTF-8,是的,以实现最大兼容性。您的 Javascript 代码将收到正确、有效的 JSON,并且可以再次将其解码为 Javascript 对象(包括 Unicode 文本)。
    猜你喜欢
    • 2017-05-17
    • 2011-11-05
    • 2012-07-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-12
    • 1970-01-01
    相关资源
    最近更新 更多