Javascript 将UTF-8 BOM添加到字符串/Blob
我需要在客户端为生成的文本数据添加一个UTF-8字节顺序标记。我该怎么做 当然,使用Javascript 将UTF-8 BOM添加到字符串/Blob,javascript,utf-8,blob,fileapi,byte-order-mark,Javascript,Utf 8,Blob,Fileapi,Byte Order Mark,我需要在客户端为生成的文本数据添加一个UTF-8字节顺序标记。我该怎么做 当然,使用newblob(['\xEF\xBB\xBF'+content])会产生“我的数据” '\uBBEF\x22BF'也不起作用(其中'\x22'==''是内容中的下一个字符) 是否可以将JavaScript中的UTF-8 BOM前置到生成的文本中 是的,在这种情况下,我确实需要UTF-8 BOM。在字符串前面加上\ufeff。请参阅 请参阅和与BOM之间的讨论。实际上,使上述工作起作用的是字符串\ufeff始终用于
newblob(['\xEF\xBB\xBF'+content])
会产生“我的数据”
'\uBBEF\x22BF'
也不起作用(其中'\x22'==''
是内容中的下一个字符)
是否可以将JavaScript中的UTF-8 BOM前置到生成的文本中
是的,在这种情况下,我确实需要UTF-8 BOM。在字符串前面加上\ufeff
。请参阅
请参阅和与BOM之间的讨论。实际上,使上述工作起作用的是字符串\ufeff
始终用于表示BOM,而不管使用的是UTF-8还是UTF-16
有关详细说明,请参见中的第36页。引用该页
表2-4中UTF-8的endian订单条目标记为N/A,因为
UTF-8代码单元的大小为8位,通常机器的问题是
较大代码单元的endian顺序不适用。序列化顺序
字节的大小不能偏离UTF-8定义的顺序
编码形式。既不要求也不建议使用BOM
UTF-8,但在使用UTF-8数据的上下文中可能会遇到
从使用BOM表或BOM所在位置的其他编码表单转换而来
用作UTF-8签名
我正在编辑我的原始答案。上面的答案确实需要细化,因为这是Node.js的复杂解决方案
简单的回答是,是的,这个代码有效
很长的答案是,不,FEFF不是utf-8的字节顺序标记。显然,node在文件中写入编码时采用了某种快捷方式。FEFF是UTF16小端编码,可以在字节顺序标记wikipedia文章中看到,也可以在写入文件后在二进制文本编辑器中查看。我已经验证了这一点他的情况就是这样
显然,Node.JS使用\ufeff表示任意数量的编码。它使用\ufeff标记,并根据writeFile的第3个选项参数将其转换为正确的字节顺序标记。您在编码字符串中传递的第3个参数。Node.JS使用此编码字符串并转换\ufeff修复将字节编码转换为任何一个实际编码的字节顺序标记
UTF-8示例:
fs.writeFile(someFilename, '\ufeff' + html, { encoding: 'utf8' }, function(err) {
/* The actual byte order mark written to the file is EF BB BF */
}
UTF-16 Little Endian示例:
fs.writeFile(someFilename, '\ufeff' + html, { encoding: 'utf16le' }, function(err) {
/* The actual byte order mark written to the file is FF FE */
}
因此,您可以看到\ufeff只是一个标记,表示任意数量的结果编码。使其进入文件的实际编码直接依赖于指定的编码选项。字符串中使用的标记实际上与写入文件的内容无关
我怀疑这背后的原因是,他们选择不写入字节顺序标记,UTF-8的3字节标记不容易编码到要写入磁盘的javascript字符串中。因此,他们使用UTF16LE BOM作为字符串中的占位符标记,该标记在写入时被替换。我也有同样的问题,这就是我提出的解决方案是:
var blob = new Blob([
new Uint8Array([0xEF, 0xBB, 0xBF]), // UTF-8 BOM
"Text",
... // Remaining data
],
{ type: "text/plain;charset=utf-8" });
使用Uint8Array
可防止浏览器将这些字节转换为字符串(在Chrome和Firefox上测试)
您应该用所需的MIME类型替换text/plain
。这是我的解决方案:
var blob = new Blob(["\uFEFF"+csv], {
type: 'text/csv; charset=utf-18'
});
好吧,如果你看一下字节顺序标记和我最初所说的,它是对的。FEFF字节顺序标记不是你在问题中所说的UTF-8的字节顺序标记。原始答案似乎偶然发现了正确的答案,或者至少根本没有详细说明。他们正确的唯一原因是因为选项编码defutf-8的错误。不是因为他们提供的字节顺序标记实际上是utf-8字节顺序标记。请随意删除我答案中的标记。这没有错。我对此有点困惑,因为问题根本没有提到节点。具体来说,您可以确定BOM始终是相同的字符(U+FEFF),而不是一个不同的字符,这取决于文本的Unicode或endianness类型。写入的字节确实不同,但这是因为同一个字符使用不同的编码写入。在接受的答案中添加了一些详细信息,以详细说明此操作的原因。请随意编辑。伙计…是的。这非常有效。谢谢!在其他问题上有太多错误/无效的答案。阅读本文的任何人都要注意:因为\ufeff
实际上是UTF-16 BOM,而不是UTF-8 BOM伟大的解决方案。谢谢@erik-töyrä@mEnE,因为\t(代码点U+0009)是<127,\t在UTF-8中是0x09,就像在UTF-16(0x0009)中一样。唯一的区别是字节的物理存储顺序。在UTF-8 0x09中。在UTF-16 LE 0x09,0x00中。在UTF-16中为0x00,0x09。只是一个小说明:字符\uFEFF是所有UTF的BOM字符(8,16 LE和16 BE)。但是,它被编码为字节:-0xEF 0xBB 0xBF-0xFF 0xFE-0xFE 0xFF。区分内部unicode字符(\ufeff)很重要,以及表示一个字符的各种方式,以字节为单位。:)当使用Blob
或使用实际字节而不是JS字符串时,这是正确的方法。当使用JS字符串而不是实际字节时,Erik和Jeff的回答是正确的。