J'essaie de télécharger un fichier binaire en utilisant XMLHttpRequest
(en utilisant un Webkit récent) et coder son contenu en utilisant cette simple fonction :
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);
À titre d'information, tout ce qui précède est du matériel Javascript standard, notamment btoa()
y encodeURIComponent()
: https://developer.mozilla.org/en/DOM/window.btoa
Cela fonctionne assez bien, et je peux même décoder le contenu en base64 en utilisant Javascript :
function base64decode(base64) {
return decodeURIComponent(escape(atob(base64)));
}
var decodedBinary = base64decode(base64encoded);
decodedBinary === binary // true
Maintenant, je veux décoder le contenu codé en base64 en utilisant Python qui consomme une chaîne JSON pour obtenir l'information suivante base64encoded
valeur de chaîne. Naïvement, c'est ce que je fais :
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()
Mais le fichier résultant n'est pas valide, il semble que l'opération se soit embrouillée avec UTF-8, l'encodage ou quelque chose qui n'est toujours pas clair pour moi.
Si j'essaie de décoder les contenus UTF-8 avant de les placer dans le fichier de destination, une erreur est levée :
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)
Pour l'anecdote, voici une capture d'écran de deux représentations textuelles d'un même fichier ; à gauche : l'original ; à droite : celui créé à partir de la chaîne décodée en base64 : http://cl.ly/0U3G34110z3c132O2e2x
Existe-t-il une astuce connue pour contourner ces problèmes d'encodage lorsque l'on tente de recréer le fichier ? Comment y parviendriez-vous vous-même ?
Toute aide ou indication sera appréciée :)