Я пытаюсь загрузить двоичный файл с помощью XMLHttpRequest
(используя недавний Webkit) и base64-кодировать его содержимое с помощью этой простой функции:
function getBinary(file){
var xhr = new XMLHttpRequest();
xhr.open("GET", file, false);
xhr.overrideMimeType("text/plain; charset=x-user-defined");
xhr.send(null);
return xhr.responseText;
}
function base64encode(binary) {
return btoa(unescape(encodeURIComponent(binary)));
}
var binary = getBinary('http://some.tld/sample.pdf');
var base64encoded = base64encode(binary);
В качестве побочного примечания все вышеперечисленное является стандартным материалом Javascript, включая btoa()
и encodeURIComponent()
: https://developer.mozilla.org/en/DOM/window.btoa
Это работает довольно гладко, и я могу даже декодировать содержимое base64 с помощью Javascript:
function base64decode(base64) {
return decodeURIComponent(escape(atob(base64)));
}
var decodedBinary = base64decode(base64encoded);
decodedBinary === binary // true
Теперь я хочу декодировать содержимое, закодированное в base64, используя Python, который потребляет некоторую строку JSON для получения строкового значения base64encoded
. Наивно это то, что я делаю:
import urllib
import base64
# ... retrieving of base64 encoded string through JSON
base64 = "77+9UE5HDQ……………oaCgA="
source_contents = urllib.unquote(base64.b64decode(base64))
destination_file = open(destination, 'wb')
destination_file.write(source_contents)
destination_file.close()
Но результирующий файл недействителен, выглядит как операция, запутанная с кодировкой UTF-8, или что-то, что до сих пор неясно.
Если я пытаюсь декодировать содержимое UTF-8 перед тем, как поместить их в файл назначения, возникает ошибка:
import urllib
import base64
# ... retrieving of base64 encoded string through JSON
base64 = "77+9UE5HDQ……………oaCgA="
source_contents = urllib.unquote(base64.b64decode(base64)).decode('utf-8')
destination_file = open(destination, 'wb')
destination_file.write(source_contents)
destination_file.close()
$ python test.py
// ...
UnicodeEncodeError: 'ascii' codec can't encode character u'\ufffd' in position 0: ordinal not in range(128)
В качестве дополнительной заметки здесь приведен снимок экрана из двух текстовых представлений одного и того же файла; слева: оригинал; справа: тот, который создан из base64-декодированной строки: http://cl.ly/0U3G34110z3c132O2e2x
Есть ли известный трюк, чтобы обойти эти проблемы с кодировкой при попытке воссоздать файл? Как бы вы сами это достигли?
Любая помощь или подсказка очень ценится:)