2016-12-27 52 views
1

我需要做的是最好的描述爲例。 以前,我有如下代碼:在JSON中發送「windows-1251」編碼的字符串從python到javascript

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

...但是...我得到了扭曲的符號。 我知道我在這裏做了一些非常錯誤的事情,並且很可能會弄亂編碼方面的事情,但仍然有一整天我無法解決這個問題。有人可以提示我的錯誤在哪裏嗎?

回答

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中),或者爲您提供Unicode文本(Python 3),以後可以將其編碼爲UTF-8。那麼你的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編碼文本是二進制數據)可在文本被編碼爲Base64:

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數據的字節串,所以它作爲ASCII用於解碼JSON庫,它希望文本是Unicode文本。

現在,您正在將以Base64文本編碼包裝的二進制數據發送到Javascript客戶端,如果您需要二進制有效內容,那麼現在必須解碼Base64。

+0

我是否正確理解,如果我沒有提及任何編碼,那麼內容將是utf-8? –

+1

@EdgarNavasardyan:Python 2中的Python json庫默認編碼爲UTF-8,是的,以實現最大的兼容性。您的Javascript代碼將收到正確,有效的JSON,並可以再次解碼爲Javascript對象(包括Unicode文本)。 –