将UTF-8 BOM添加到字符串/ Blob

kay*_*kay 44 javascript byte-order-mark blob utf-8 fileapi

我需要在客户端为生成的文本数据添加UTF-8字节顺序标记.我怎么做?

当然,使用new Blob(['\xEF\xBB\xBF' + content])产量'"my data"'.

也没有'\uBBEF\x22BF'工作('\x22' == '"'成为下一个角色content).

是否可以将JavaScript中的UTF-8 BOM添加到生成的文本中?

是的,在这种情况下我确实需要UTF-8 BOM.

Eri*_*ärd 107

前置\ufeff字符串.请参阅http://msdn.microsoft.com/en-us/library/ie/2yfce773(v=vs.94).aspx

有关UTF-8和UTF-16以及BOM的详细信息,请参阅@ jeff-fischer@casey 之间的讨论.实际上做的是,无论使用UTF-8还是UTF-16 ,字符串始终用于表示BOM.\ufeff

有关详细说明,请参阅Unicode标准5.0第2章第36页.该页面的引用

表2-4中UTF-8的字节顺序条目标记为N/A,因为UTF-8代码单元的大小为8位,而较大代码单元的端序顺序的常见机器问题不适用.字节的序列化顺序不得偏离UTF-8编码格式定义的顺序.对于UTF-8既不要求也不建议使用BOM,但在从使用BOM的其他编码形式或将BOM用作UTF-8签名的UTF-8数据转换的上下文中可能会遇到.

  • 对阅读本文的其他人的警告:请注意,因为 `\ufeff` 实际上是 UTF-16 BOM,而不是 UTF-8 BOM https://en.wikipedia.org/wiki/Byte_order_mark (4认同)
  • 只是一个小小的澄清:_character_\uFEFF是所有UTF的BOM字符(8,16 LE和16 BE).但是,它被_encoded_作为字节: - 0xEF 0xBB 0xBF - 0xFF 0xFE - 0xFE 0xFF.区分内部unicode字符(\ ufeff)和表示一个字符的各种方式(以字节为单位)非常重要.:) (4认同)

car*_*lgn 15

我有同样的问题,这是我提出的解决方案:

var blob = new Blob([
                    new Uint8Array([0xEF, 0xBB, 0xBF]), // UTF-8 BOM
                    "Text",
                    ... // Remaining data
                    ],
                    { type: "text/plain;charset=utf-8" });
Run Code Online (Sandbox Code Playgroud)

使用Uint8Array可防止浏览器将这些字节转换为字符串(在Chrome和Firefox上测试).

您应该替换text/plain为您想要的MIME类型.


Jef*_*her 13

我正在编辑我的原始答案.上面的回答确实需要详细说明,因为这是Node.js的一个复杂的解决方案.

简短的回答是,这个代码有效.

答案很长,不,FEFF不是utf-8的字节顺序标记.显然,节点采用某种快捷方式在文件中编写编码.FEFF是UTF16 Little Endian编码,可以在Byte Order Mark维基百科文章中看到,也可以在编写文件后在二进制文本编辑器中查看.我已经证实了这种情况.

http://en.wikipedia.org/wiki/Byte_order_mark#Representations_of_byte_order_marks_by_encoding

显然,Node.JS使用\ ufeff来表示任意数量的编码.它接受\ ufeff标记,并根据writeFile的3rd选项参数将其转换为正确的字节顺序标记.您在编码字符串中传递的第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 */
}
Run Code Online (Sandbox Code Playgroud)

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 */
}
Run Code Online (Sandbox Code Playgroud)

因此,正如您所看到的,\ ufeff只是一个标记,表明任何数量的结果编码.使其进入文件的实际编码直接依赖于指定的编码选项.字符串中使用的标记实际上与写入文件的内容无关.

我怀疑这背后的原因是因为他们选择不写字节顺序标记,而UTF-8的3字节标记不容易编码到要写入磁盘的javascript字符串中.因此,他们使用UTF16LE BOM作为字符串中的占位符标记,该标记在写入时被替换.

  • 具体来说,你可以[见这里](http://en.wikipedia.org/wiki/Byte_order_mark),BOM总是相同的字符(U + FEFF),而不是一个不同的字符,具体取决于Unicode或字节序的类型文本是在.确实写入的字节是不同的,但这是因为相同的字符是用不同的编码写的. (7认同)
  • 好吧,如果你看一下字节顺序标记和我原来说的话,那是对的.如您在问题中所述,FEFF字节顺序标记不是UTF-8的字节顺序标记.原来的答案似乎偶然发现了正确的答案,或者至少没有详细说明.他们做对的唯一原因是因为选项编码默认为utf-8.不是因为它们提供的字节顺序标记实际上是UTF-8字节顺序标记. (2认同)
  • 我对此有点困惑,因为这个问题根本没有提到节点。 (2认同)
  • 在接受的答案中添加了一些细节,以详细说明其工作原理.您可以根据需要随意编辑. (2认同)

小智 9

这是我的解决方案:

var blob = new Blob(["\uFEFF"+csv], {
type: 'text/csv; charset=utf-18'
});
Run Code Online (Sandbox Code Playgroud)

  • 你能解释一下为什么这样工作吗? utf-18 是一种有效的编码吗 (3认同)