utf-8 编码的字符串到缓冲区 node.js
utf-8 encoded String to Buffer node.js
在 nodejs express 服务器 #1 上,我在 HTTP 响应中从另一个 nodejs 服务器 #2 接收二进制流数据。我想将此数据编码为 base64。我有编码问题。我做了如下所示。
let result = await axios.post(firmwareDownloadURL, {
id: 'firmware1'
}, {
headers: {
'Content-Type': 'application/json',
}
});
let buff1 = new Buffer.from(result.data);
let base64Firmware1 = buff1.toString('base64');
buff1
的值不正确,因此base64Firmware1
也是错误的。我通过使用 fs.
从我的系统读取固件文件来比较它
let buff2 = fs.readFileSync('./f1.bin');
let base64Firmware2 = buff3.toString('base64');
buff1
和 buff2
不匹配。
buff <Buffer ef bf bd ef bf bd ef bf bd 00 01 ef bf bd 48 ef bf bd ef bf bd 01 6d 02 08 22 ef bf bd ef bf bd 0a ef bf bd ef bf bd 6e 6d 02 08 ef bf bd 0a ef bf bd ... 612 more bytes>
buff2 <Buffer a7 a3 fe 00 01 8d 48 a7 a6 01 6d 02 08 22 a7 a3 0a a7 a6 6e 6d 02 08 f1 a7 a3 0a a7 a6 f7 6d 02 08 b4 a7 a3 32 a7 a6 14 6e 02 08 39 a7 a3 06 a7 a6 56 ... 307 more bytes>
有趣的是,当我将 buff2
转换为字符串并与 result.data
进行比较时,它们匹配。
if (buff2.toString() === result.data && buff2.toString().length == result.data.length) {
console.log('equal');
}
它在控制台上打印相等。请帮助我识别,我错过了什么?
您观察到数据在字符串化时匹配是正确的,因为这正是 Axios 在幕后所做的。问题是 Axios 默认情况下会将响应数据字符串化。在 Node.js 上,这意味着 it calls Buffer.toString('utf8')
which produces what you see. As a result, the bytes are interpreted as UTF-8, which turns invalid code units into the U+FFFD REPLACEMENT CHARACTER
Unicode code point, as specified in the documentation for Buffer.toString()
:
If encoding
is 'utf8'
and a byte sequence in the input is not valid UTF-8, then each invalid byte is replaced with the replacement character U+FFFD
.
U+FFFD
代码点以 UTF-8 编码为代码单元 EF BF BD
,您在数据中看到了这一点。
事后将已经字符串化的缓冲区变成原始缓冲区是不可能的,因为所有非 UTF8 代码单元都变成了 U+FFFD
,这会丢失信息。要解决编码问题,您可以使用 Axios 中的 responseType
选项来指定您想要原始缓冲区:
let res = await axios.post(
firmwareDownloadURL,
{
id: "firmware1",
},
{
headers: {
"Content-Type": "application/json",
},
responseType: "arraybuffer",
}
);
let buff1 = res.data;
let base64Firmware1 = buff1.toString("base64");
Valid options 对于 responseType
是 'arraybuffer'
、'document'
、'json'
、'text'
、'stream'
,当在浏览器环境中使用 Axios,'blob'
.
附带说明一下,如果您有兴趣了解更多有关 Unicode“代码点”到底是什么的信息,我建议您阅读 this article。
在 nodejs express 服务器 #1 上,我在 HTTP 响应中从另一个 nodejs 服务器 #2 接收二进制流数据。我想将此数据编码为 base64。我有编码问题。我做了如下所示。
let result = await axios.post(firmwareDownloadURL, {
id: 'firmware1'
}, {
headers: {
'Content-Type': 'application/json',
}
});
let buff1 = new Buffer.from(result.data);
let base64Firmware1 = buff1.toString('base64');
buff1
的值不正确,因此base64Firmware1
也是错误的。我通过使用 fs.
let buff2 = fs.readFileSync('./f1.bin');
let base64Firmware2 = buff3.toString('base64');
buff1
和 buff2
不匹配。
buff <Buffer ef bf bd ef bf bd ef bf bd 00 01 ef bf bd 48 ef bf bd ef bf bd 01 6d 02 08 22 ef bf bd ef bf bd 0a ef bf bd ef bf bd 6e 6d 02 08 ef bf bd 0a ef bf bd ... 612 more bytes>
buff2 <Buffer a7 a3 fe 00 01 8d 48 a7 a6 01 6d 02 08 22 a7 a3 0a a7 a6 6e 6d 02 08 f1 a7 a3 0a a7 a6 f7 6d 02 08 b4 a7 a3 32 a7 a6 14 6e 02 08 39 a7 a3 06 a7 a6 56 ... 307 more bytes>
有趣的是,当我将 buff2
转换为字符串并与 result.data
进行比较时,它们匹配。
if (buff2.toString() === result.data && buff2.toString().length == result.data.length) {
console.log('equal');
}
它在控制台上打印相等。请帮助我识别,我错过了什么?
您观察到数据在字符串化时匹配是正确的,因为这正是 Axios 在幕后所做的。问题是 Axios 默认情况下会将响应数据字符串化。在 Node.js 上,这意味着 it calls Buffer.toString('utf8')
which produces what you see. As a result, the bytes are interpreted as UTF-8, which turns invalid code units into the U+FFFD REPLACEMENT CHARACTER
Unicode code point, as specified in the documentation for Buffer.toString()
:
If
encoding
is'utf8'
and a byte sequence in the input is not valid UTF-8, then each invalid byte is replaced with the replacement characterU+FFFD
.
U+FFFD
代码点以 UTF-8 编码为代码单元 EF BF BD
,您在数据中看到了这一点。
事后将已经字符串化的缓冲区变成原始缓冲区是不可能的,因为所有非 UTF8 代码单元都变成了 U+FFFD
,这会丢失信息。要解决编码问题,您可以使用 Axios 中的 responseType
选项来指定您想要原始缓冲区:
let res = await axios.post(
firmwareDownloadURL,
{
id: "firmware1",
},
{
headers: {
"Content-Type": "application/json",
},
responseType: "arraybuffer",
}
);
let buff1 = res.data;
let base64Firmware1 = buff1.toString("base64");
Valid options 对于 responseType
是 'arraybuffer'
、'document'
、'json'
、'text'
、'stream'
,当在浏览器环境中使用 Axios,'blob'
.
附带说明一下,如果您有兴趣了解更多有关 Unicode“代码点”到底是什么的信息,我建议您阅读 this article。