我需要在客户端为生成的文本数据添加一个 UTF-8 字节顺序标记。我怎么做?
当然,使用new Blob(['\xEF\xBB\xBF' + content])
yields '"my data"'
。
也没有'\uBBEF\x22BF'
工作('\x22' == '"'
作为 中的下一个字符content
)。
是否可以将 JavaScript 中的 UTF-8 BOM 添加到生成的文本中?
是的,在这种情况下,我确实需要 UTF-8 BOM。
我需要在客户端为生成的文本数据添加一个 UTF-8 字节顺序标记。我怎么做?
当然,使用new Blob(['\xEF\xBB\xBF' + content])
yields '"my data"'
。
也没有'\uBBEF\x22BF'
工作('\x22' == '"'
作为 中的下一个字符content
)。
是否可以将 JavaScript 中的 UTF-8 BOM 添加到生成的文本中?
是的,在这种情况下,我确实需要 UTF-8 BOM。
前置\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
有关详细说明,请参阅The Unicode Standard 5.0, Chapter 2中的第 36 页。来自该页面的引用
表 2-4 中 UTF-8 的字节序条目标记为 N/A,因为 UTF-8 代码单元的大小为 8 位,并且较大代码单元的字节序的常见机器问题不适用。字节的序列化顺序不得偏离 UTF-8 编码格式定义的顺序。对于 UTF-8,既不需要也不建议使用 BOM,但在使用 BOM 的其他编码形式转换 UTF-8 数据或将 BOM 用作 UTF-8 签名的情况下可能会遇到这种情况。
我有同样的问题,这是我想出的解决方案:
var blob = new Blob([
new Uint8Array([0xEF, 0xBB, 0xBF]), // UTF-8 BOM
"Text",
... // Remaining data
],
{ type: "text/plain;charset=utf-8" });
使用Uint8Array
防止浏览器将这些字节转换为字符串(在 Chrome 和 Firefox 上测试)。
您应该替换text/plain
为您想要的 MIME 类型。
我正在编辑我的原始答案。上面的答案确实需要详细说明,因为这是 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 来表示任意数量的 encoding。它采用 \ufeff 标记并根据 writeFile 的第三个选项参数将其转换为正确的字节顺序标记。您在编码字符串中传递的第三个参数。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 小端示例:
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(["\uFEFF"+csv], {
type: 'text/csv; charset=utf-18'
});