【发布时间】:2011-11-14 07:36:57
【问题描述】:
我正在尝试使用 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
这很顺利,我什至可以使用 Javascript 解码 base64 内容:
function base64decode(base64) {
return decodeURIComponent(escape(atob(base64)));
}
var decodedBinary = base64decode(base64encoded);
decodedBinary === binary // true
现在,我想使用 Python 解码 base64 编码的内容,它使用一些 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
在尝试重新创建文件时,是否有已知的技巧来规避这些编码问题?您自己将如何实现这一目标?
非常感谢任何帮助或提示:)
【问题讨论】:
-
作为旁注,我尝试使用
codecs模块来使用'utf-8'编解码器编写目标文件,但也没有运气,但我可能在某个地方搞砸了. -
这很奇怪,因为 \ufffd 很特别:fileformat.info/info/unicode/char/fffd/index.htm
-
@rocksportrocker> 那会假设我正在使用的
base64encode()函数无法转换某些字符......奇怪的是反向操作在javascript中完美运行...... -
您是否尝试在不同的步骤中转储第一个字节值。看起来一个或您的库太聪明了,没有在字节级别进行转换。我建议创建一个具有 >255 个代码点的简单 UTF-8 文本文件,并在每一步手动分析字节值。你应该在错误的地方停下来。
-
不幸的是,我没有使用任何库……JS 的东西(
btoa()、encodeURIComponent()和unescape())是标准的。 Python 部分也是如此,除了 stdlib 使用的东西……我将使用奇怪的 Bytes 值进行调查,这看起来真的很痛苦:(
标签: javascript python encoding xmlhttprequest base64