我一直在玩一些JS加密库(CryptoJS,SJCL),并发现了与Blob / File API和JavaScript“二进制字符串”相关的问题。
我意识到加密甚至不是真正相关的,所以这是一个非常简化的场景。只需使用readAsBinaryString读取文件,然后创建一个Blob:
>>> reader.result
"GIF89a����ÿÿÿÿÿÿ!þCreated with GIMP�,�������D�;"
>>> reader.result.length
56
>>> typeof reader.result
"string"
>>> blob = new Blob([reader.result], {type: "image/gif"})
Blob { size=64, type="image/gif", constructor=function(), more...}
我已经创建了一个基本上可以执行上述操作的JSFiddle:它只是读取任意文件,从中创建blob,并输出长度与大小: http://jsfiddle.net/6L82t/1/
看来,当从“二进制(javascript)字符串”创建Blob时,带有字符编码的内容最终会重置结果。
如果使用非二进制文件,您将看到Blob和原始二进制字符串的长度相同。
因此,尝试从非纯文本Javascript字符串创建Blob /文件时会发生一些事情,我需要做任何不会发生的事情。我认为它可能与JS字符串是UTF-16的事实有关吗?
这里有一个(可能)相关的主题: HTML5 File API read as text and binary
在将它们放入Blob / File之前,我是否需要获取解密结果(UTF-16)并将它们“转换”为UTF-8?
在Freenode的#html5中与某人合作,我们确定如果你直接读取一个ArrayBuffer,然后通过首先使用Uint8Array创建blob,那么字节就可以了。您可以在这里看到一个基本上可以做到的小提琴: http://jsfiddle.net/GH7pS/4/
问题是,至少在我的场景中,我将最终得到一个二进制字符串,并想弄清楚如何将其直接转换为Blob,以便我可以使用html5的下载来允许用户点击直接下载blob。
谢谢!
答案 0 :(得分:17)
看来,当从"二进制(javascript)字符串"创建Blob时,带有字符编码的内容最终会重置结果。
是。 That post you read很好地解释了"二进制字符串"是的。
- 让
s
成为使用算法将[字符串]转换为Unicode characters序列的结果 在WebIDL中这样做。- 将
醇>s
编码为UTF-8,并将结果字节附加到[blob]。
我们确定如果你直接读取一个ArrayBuffer,然后首先使用Uint8Array从中创建blob,那么字节就可以正常工作。
是的,这是应该如何运作的。只需在Typed Array上进行加密,你可以单独处理字节,而不是在某些字符串上。
问题是,至少在我的场景中,我最终会得到一个二进制字符串
再次:尽量不要。 binary strings are deprecated
我想弄清楚如何将二进制字符串直接转换为Blob。我是否需要采取解密结果(UTF-16)和"转换"在将它们放入Blob / File之前将它们转换为UTF-8?
不,最好不要尝试进行任何字符串转换。相反,为要从二进制字符串中获取的字节构造一个Uint8Array
(Uint8Array)。
这应该做(未经测试):
var bytes = new Uint8Array(str.length);
for (var i=0; i<str.length; i++)
bytes[i] = str.charCodeAt(i);