保存 HTML Blob 文件会在里面产生奇怪的文本
Saving an HTML Blob file produces weird text inside
所以我有一个逗号分隔的文件,我正在保存到一个 blob。
我正在使用最新的基于 Chrome 的 Edge 浏览器。
我拥有的这个特定代码(打字稿)已经好几个月没有改变了。
但突然间,我注意到如果我保存文件时包含一个特定的日期时间字符串,那么我会得到一个奇怪的输出。基本上,我看到的是奇怪的文本而不是日期时间字符串。
这是我正在保存的日期时间字符串(并且完全希望在保存的文件中看到):
9/26/2020 7:00:00 AM
这里出现的是奇怪的文字:
‎9‎/‎26‎/‎2020‎ ‎7‎:‎00‎:‎00‎ ‎AM
现在判断我不能简单地将这个奇怪的字符串复制并粘贴到这个编辑中 window(它认为我试图粘贴图像),我猜它是二进制的。这可能是一个很大的提示,但对我来说没有任何意义。
所以问题是:当我确定我正在写出一个字符串时,为什么这个二进制文件?
经过一番深入研究后,我确定似乎存在编码问题。仍然不确定为什么。此外,仔细检查奇怪的字符串,日期实际上就在那里。它看起来很奇怪,因为每个组件都用这个奇怪的字符串“-”填充。
你的字符串全是Unicode Character 'LEFT-TO-RIGHT MARK' (U+200E).
const text = `9/26/2020 7:00:00 AM`;
console.log( text.replace( /\u200e/g, "[LTR]" ) );
不知何故,您正在以 Windows-1252 格式读取您的文件(您没有说明您是如何读取它的,因此很难告诉您您做错了什么,但请注意这是默认编码在大多数浏览器中直接打开文本文件时),并且当 reader 找到 UTF-8 0xe2 0x80 0x8e
序列时,它在 Windows-1252 中映射得不好(不像其他 ASCII字符)并且这个字符被读取为 ‎
:
const text = "\u200e9\u200e/\u200e26\u200e/\u200e2020\u200e \u200e7\u200e:\u200e00\u200e:\u200e00\u200e \u200eAM";
const blob = new Blob( [ text ] ); // here 'text' is encoded as UTF-8
const reader = new FileReader();
reader.onload = (evt) => {
console.log( reader.result );
const OPs_result = "‎9‎/‎26‎/‎2020‎ ‎7‎:‎00‎:‎00‎ ‎AM";
console.log( "is same as OP's result?", OPs_result === reader.result );
};
reader.readAsText( blob, "Windows-1252" );
但是,以 UTF-8 读取同一文件将正确呈现这些字符:
const text = "\u200e9\u200e/\u200e26\u200e/\u200e2020\u200e \u200e7\u200e:\u200e00\u200e:\u200e00\u200e \u200eAM";
const blob = new Blob( [ text ] ); // here 'text' is encoded as UTF-8
blob.text() // reads as UTF-8
.then( console.log );
如果您想帮助您的浏览器以 UTF-8 而不是默认的 Windows-1252 格式打开此文本文件,您可以在此文件前添加一个 BOM,如 in this answer 所示:
const text = "\u200e9\u200e/\u200e26\u200e/\u200e2020\u200e \u200e7\u200e:\u200e00\u200e:\u200e00\u200e \u200eAM";
const without_BOM = new Blob( [ text ] );
const BOM = new Uint8Array([0xEF,0xBB,0xBF]);
const with_BOM = new Blob( [ BOM, text ] );
document.getElementById( "without_BOM" ).href = URL.createObjectURL( without_BOM );
document.getElementById( "with_BOM" ).href = URL.createObjectURL( with_BOM );
<a id="without_BOM">Open the file without BOM</a><br>
<a id="with_BOM">Open the file with BOM</a>
如果您希望将您的 csv 文件编码为 Windows-1252,那么您可以检查 this answer.
所以我有一个逗号分隔的文件,我正在保存到一个 blob。 我正在使用最新的基于 Chrome 的 Edge 浏览器。 我拥有的这个特定代码(打字稿)已经好几个月没有改变了。 但突然间,我注意到如果我保存文件时包含一个特定的日期时间字符串,那么我会得到一个奇怪的输出。基本上,我看到的是奇怪的文本而不是日期时间字符串。
这是我正在保存的日期时间字符串(并且完全希望在保存的文件中看到):
9/26/2020 7:00:00 AM
这里出现的是奇怪的文字:
‎9‎/‎26‎/‎2020‎ ‎7‎:‎00‎:‎00‎ ‎AM
现在判断我不能简单地将这个奇怪的字符串复制并粘贴到这个编辑中 window(它认为我试图粘贴图像),我猜它是二进制的。这可能是一个很大的提示,但对我来说没有任何意义。
所以问题是:当我确定我正在写出一个字符串时,为什么这个二进制文件?
经过一番深入研究后,我确定似乎存在编码问题。仍然不确定为什么。此外,仔细检查奇怪的字符串,日期实际上就在那里。它看起来很奇怪,因为每个组件都用这个奇怪的字符串“-”填充。
你的字符串全是Unicode Character 'LEFT-TO-RIGHT MARK' (U+200E).
const text = `9/26/2020 7:00:00 AM`;
console.log( text.replace( /\u200e/g, "[LTR]" ) );
不知何故,您正在以 Windows-1252 格式读取您的文件(您没有说明您是如何读取它的,因此很难告诉您您做错了什么,但请注意这是默认编码在大多数浏览器中直接打开文本文件时),并且当 reader 找到 UTF-8 0xe2 0x80 0x8e
序列时,它在 Windows-1252 中映射得不好(不像其他 ASCII字符)并且这个字符被读取为 ‎
:
const text = "\u200e9\u200e/\u200e26\u200e/\u200e2020\u200e \u200e7\u200e:\u200e00\u200e:\u200e00\u200e \u200eAM";
const blob = new Blob( [ text ] ); // here 'text' is encoded as UTF-8
const reader = new FileReader();
reader.onload = (evt) => {
console.log( reader.result );
const OPs_result = "‎9‎/‎26‎/‎2020‎ ‎7‎:‎00‎:‎00‎ ‎AM";
console.log( "is same as OP's result?", OPs_result === reader.result );
};
reader.readAsText( blob, "Windows-1252" );
但是,以 UTF-8 读取同一文件将正确呈现这些字符:
const text = "\u200e9\u200e/\u200e26\u200e/\u200e2020\u200e \u200e7\u200e:\u200e00\u200e:\u200e00\u200e \u200eAM";
const blob = new Blob( [ text ] ); // here 'text' is encoded as UTF-8
blob.text() // reads as UTF-8
.then( console.log );
如果您想帮助您的浏览器以 UTF-8 而不是默认的 Windows-1252 格式打开此文本文件,您可以在此文件前添加一个 BOM,如 in this answer 所示:
const text = "\u200e9\u200e/\u200e26\u200e/\u200e2020\u200e \u200e7\u200e:\u200e00\u200e:\u200e00\u200e \u200eAM";
const without_BOM = new Blob( [ text ] );
const BOM = new Uint8Array([0xEF,0xBB,0xBF]);
const with_BOM = new Blob( [ BOM, text ] );
document.getElementById( "without_BOM" ).href = URL.createObjectURL( without_BOM );
document.getElementById( "with_BOM" ).href = URL.createObjectURL( with_BOM );
<a id="without_BOM">Open the file without BOM</a><br>
<a id="with_BOM">Open the file with BOM</a>
如果您希望将您的 csv 文件编码为 Windows-1252,那么您可以检查 this answer.