【问题标题】:How to force UTF-8 in node js with exec process?如何使用 exec 进程在节点 js 中强制使用 UTF-8?
【发布时间】:2018-03-18 03:03:22
【问题描述】:

我知道解决方案很简单,但我要花一个小时才能解决问题。

Windows 10 中,如果我启动命令“dir”,我会得到以下结果:

Il volume nell'unità D non ha etichetta.

Node js 中,我尝试以这种方式执行 dir 命令:

var child = exec('dir', {'encoding': 'UTF-8'}, (err, stdout, stderr) => {
  console.log(stdout);
});

我得到了这个结果: Il volume nell'unit. C non ha etichetta.

啊,该死的重音字母!

我尝试使用 UTF-16,然后转换为字符串:

var child = exec('dir', {'encoding': 'UTF-16'}, (err, stdout, stderr) => {
  let b: Buffer = stdout;
  let o: string;
  o = stdout.toString('UTF-8');
  console.log(o);
});

我得到了同样的诅咒结果:

“Il volume nell'unit。C non ha etichetta。”

你能帮我解决这个问题吗? 我做错了什么?

exec 命令似乎不接受 UTF-8 编码 事实上,如果我运行这个脚本来强制从 UTF-8 转换为字符串:

var child = exec(j.cmd, {'encoding': 'UTF-8'}, (err, stdout, stderr) => {
  var utf8 = require('utf8');
  var o: string = utf8.decode(stdout)
  console.log(o);
});

我收到了这个错误:

..\node_modules\utf8\utf8.js:194 throw Error('检测到无效的 UTF-8');

有什么想法吗?

【问题讨论】:

    标签: node.js utf-8 exec utf-16


    【解决方案1】:

    当您在命令提示符中使用 dir 时,渲染器知道 stdout 正在使用哪种字符编码,解码文本字节并使用所选字体渲染字符。

    当你执行一个命令时,node 不知道 stdout 使用的是哪种字符编码,所以你告诉它。问题是你告诉它错误的事情。要查看它是哪种字符编码,请转到chcp。但是,开箱即用的 node 只支持几十种字符编码中的一部分。

    解决方案是告诉命令提示符使用它们共同的一个。由于您从文件系统获取路径,并且文件系统 (NTFS) 使用 Unicode 字符集作为路径,因此 UTF-8 是一个不错的选择。

    所以,这应该可行:

    exec('@chcp 65001 >nul & dir', {encoding: "UTF-8"}, 
        (err, stdout, stderr) => console.log(stdout));
    

    但是,chcp 命令有延迟效果,不适用于 dir 命令。这是解决此问题的一种方法:

    exec('@chcp 65001 >nul & cmd /d/s/c dir', {encoding: "UTF-8"}, 
        (err, stdout, stderr) => console.log(stdout));
    

    运行批处理文件可能是一种更简单的方法,可以让两个单独的命令按顺序运行,但这需要设置和清理。

    【讨论】:

      【解决方案2】:

      Node.js不支持windowscmd.exe使用的你的编码,所以你必须使用像iconv-lite这样的库来转换它。

      var child = exec('dir', {'encoding': 'buffer'}, (err, stdout, stderr) => {
        console.log(iconv.decode(stdout, 'CP936'));
      });
      
      1. 使用buffer 获取原始原始字符串
      2. 替换你的编码字符串而不是'CP936'。您可以在 cmd.exe > 属性 > 代码页中找到它。

      更新:替换为您所在国家/地区的编码也可以正常工作。在我的例子中,'GB18030''GBK' 包含 'CP936',两者都可以使用。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-03-28
        • 2016-12-14
        • 2011-12-10
        • 2016-03-11
        • 1970-01-01
        • 2021-06-09
        • 2011-11-17
        相关资源
        最近更新 更多