我需要在客户端为生成的文本数据添加UTF-8字节顺序标记。我该怎么做?
当然,使用new Blob(['\xEF\xBB\xBF' + content])
会产生'"my data"'
。
'\uBBEF\x22BF'
也没有工作('\x22' == '"'
成为content
中的下一个字符。)
是否可以将JavaScript中的UTF-8 BOM添加到生成的文本中?
是的,在这种情况下我确实需要UTF-8 BOM。
答案 0 :(得分:92)
将\ufeff
添加到字符串中。见http://msdn.microsoft.com/en-us/library/ie/2yfce773(v=vs.94).aspx
请参阅@jeff-fischer和@casey for details on UTF-8 and UTF-16与BOM之间的讨论。实际上,上述工作的结果是,无论使用的是UTF-8还是UTF-16,字符串\ufeff
始终用于表示BOM。
有关详细说明,请参阅The Unicode Standard 5.0, Chapter 2中的第36页。该页面的引用
表2-4中UTF-8的字节顺序条目标记为N / A,因为 UTF-8代码单元的大小为8位,通常是机器问题 较大代码单元的字节顺序不适用。序列化的订单 字节数不得偏离UTF-8定义的顺序 编码形式。不需要也不建议使用BOM UTF-8,但可能在UTF-8数据的上下文中遇到 从使用BOM或BOM所在的其他编码表单转换而来 用作UTF-8签名。
答案 1 :(得分:12)
我正在编辑我的原始答案。上面的回答确实需要详细说明,因为这是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 */
}
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作为字符串中的占位符标记,在写入时被替换。
答案 2 :(得分:10)
我遇到了同样的问题,这是我提出的解决方案:
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类型。
答案 3 :(得分:0)
这是我的解决方案:
var blob = new Blob(["\uFEFF"+csv], {
type: 'text/csv; charset=utf-18'
});
答案 4 :(得分:-1)
Google表格仍会出现特殊字符问题,选择“保存到Google表格”即可解决该问题。这就是我解决的创建文档并将其提供给用户的方式:
const columns = ["pos", "tag", "name", "cat", "time", "lag", "mode", "start", "finish"]
const rows = data.map(e => [columns.map(i => e[i])])
const handleExport = (columns, rows) => {
let blob = new Blob([new Uint8Array([0xef, 0xbb, 0xbf]), [columns, ...rows].map(e => e.join(",")).join("\n")], {
type: "text/csv;charset=utf-8",
})
window.confirm('If Google Sheets displays special characters incorectly just save to Google Sheets.')
const reader = new FileReader()
reader.readAsDataURL(blob)
reader.onload = function() {
var link = document.createElement("a")
link.setAttribute("href", reader.result)
link.setAttribute("download", currentEvent.name + ".csv")
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
}
}
转义逗号是个好主意,我在这里没有做过,但可以通过将其括在双引号(“)中来轻松实现。