NodeJS去除BOM和转换UTF8编码

 更新时间:2023年11月18日 16:56:47   投稿:yin  
使用NodeJS编写前端工具时,操作得最多的是文本文件,但遗憾的是,GBK编码不在NodeJS自身支持范围内,UTF8文件还可能带有BOM,在读取不同编码的文本文件时,需要将文件内容转换为JS使用的UTF8编码字符串后才能正常处理

使用NodeJS编写前端工具时,操作得最多的是文本文件,因此也就涉及到了文件编码的处理问题。我们常用的文本编码有UTF8GBK两种,并且UTF8文件还可能带有BOM。在读取不同编码的文本文件时,需要将文件内容转换为JS使用的UTF8编码字符串后才能正常处理。

BOM用于标记一个文本文件使用Unicode编码,其本身是一个Unicode字符("\uFEFF"),根据文本文件头几个字节等于啥来判断文件是否包含BOM,以及使用哪种Unicode编码,NodeJS支持在读取文本文件时,或者在Buffer转换为字符串时指定文本编码,但遗憾的是,GBK编码不在NodeJS自身支持范围内,因此,一般我们借助iconv-lite这个三方包来转换编码。

BOM的移除

BOM用于标记一个文本文件使用Unicode编码,其本身是一个Unicode字符("\uFEFF"),位于文本文件头部。在不同的Unicode编码下,BOM字符对应的二进制字节如下:

    Bytes      Encoding
----------------------------
    FE FF       UTF16BE
    FF FE       UTF16LE
    EF BB BF    UTF8

因此,我们可以根据文本文件头几个字节等于啥来判断文件是否包含BOM,以及使用哪种Unicode编码。但是,BOM字符虽然起到了标记文件编码的作用,其本身却不属于文件内容的一部分,如果读取文本文件时不去掉BOM,在某些使用场景下就会有问题。例如我们把几个JS文件合并成一个文件后,如果文件中间含有BOM字符,就会导致浏览器JS语法错误。因此,使用NodeJS读取文本文件时,一般需要去掉BOM。例如,以下代码实现了识别和去除UTF8 BOM的功能。

function readText(pathname) {
    var bin = fs.readFileSync(pathname);

    if (bin[0] === 0xEF && bin[1] === 0xBB && bin[2] === 0xBF) {
        bin = bin.slice(3);
    }

    return bin.toString('utf-8');
}

GBK转UTF8

NodeJS支持在读取文本文件时,或者在Buffer转换为字符串时指定文本编码,但遗憾的是,GBK编码不在NodeJS自身支持范围内。因此,一般我们借助iconv-lite这个三方包来转换编码。使用NPM下载该包后,我们可以按下边方式编写一个读取GBK文本文件的函数。

var iconv = require('iconv-lite');

function readGBKText(pathname) {
    var bin = fs.readFileSync(pathname);

    return iconv.decode(bin, 'gbk');
}

单字节编码

有时候,我们无法预知需要读取的文件采用哪种编码,因此也就无法指定正确的编码。比如我们要处理的某些CSS文件中,有的用GBK编码,有的用UTF8编码。虽然可以一定程度可以根据文件的字节内容猜测出文本编码,但这里要介绍的是有些局限,但是要简单得多的一种技术。

首先我们知道,如果一个文本文件只包含英文字符,比如Hello World,那无论用GBK编码或是UTF8编码读取这个文件都是没问题的。这是因为在这些编码下,ASCII0~128范围内字符都使用相同的单字节编码。

反过来讲,即使一个文本文件中有中文等字符,如果我们需要处理的字符仅在ASCII0~128范围内,比如除了注释和字符串以外的JS代码,我们就可以统一使用单字节编码来读取文件,不用关心文件的实际编码是GBK还是UTF8。以下示例说明了这种方法。

1\. GBK编码源文件内容:
    var foo = '中文';
2\. 对应字节:
    76 61 72 20 66 6F 6F 20 3D 20 27 D6 D0 CE C4 27 3B
3\. 使用单字节编码读取后得到的内容:
    var foo = '{乱码}{乱码}{乱码}{乱码}';
4\. 替换内容:
    var bar = '{乱码}{乱码}{乱码}{乱码}';
5\. 使用单字节编码保存后对应字节:
    76 61 72 20 62 61 72 20 3D 20 27 D6 D0 CE C4 27 3B
6\. 使用GBK编码读取后得到内容:
    var bar = '中文';

这里的诀窍在于,不管大于0xEF的单个字节在单字节编码下被解析成什么乱码字符,使用同样的单字节编码保存这些乱码字符时,背后对应的字节保持不变。

NodeJS中自带了一种binary编码可以用来实现这个方法,因此在下例中,我们使用这种编码来演示上例对应的代码该怎么写。

function replace(pathname) {
    var str = fs.readFileSync(pathname, 'binary');
    str = str.replace('foo', 'bar');
    fs.writeFileSync(pathname, str, 'binary');
}

到此这篇关于NodeJS去除BOM和转换UTF8编码的文章就介绍到这了,更多相关NodeJS去除BOM和转换编码内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 配置node服务器并且链接微信公众号接口配置步骤详解

    配置node服务器并且链接微信公众号接口配置步骤详解

    这篇文章主要介绍了配置node服务器并且链接微信公众号接口配置步骤详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,,需要的朋友可以参考下
    2019-06-06
  • Nodejs使用mysql2操作数据库的方法完整讲解

    Nodejs使用mysql2操作数据库的方法完整讲解

    MySQL2是一个基于Node.js的MySQL数据库驱动程序,它是MySQL官方推荐的驱动之一,下面这篇文章主要给大家介绍了关于Nodejs使用mysql2操作数据库的相关资料,需要的朋友可以参考下
    2024-01-01
  • NodeJS Express使用ORM模型访问关系型数据库流程详解

    NodeJS Express使用ORM模型访问关系型数据库流程详解

    这篇文章主要介绍了NodeJS Express使用ORM模型访问关系型数据库流程,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧
    2023-01-01
  • node.js实现身份认证的示例代码

    node.js实现身份认证的示例代码

    本文主要介绍了 node.js实现身份认证的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-04-04
  • node.js对于数据库MySQL基本操作实例总结【增删改查】

    node.js对于数据库MySQL基本操作实例总结【增删改查】

    这篇文章主要介绍了node.js对于数据库MySQL基本操作,结合实例形式总结分析了node.js针对mysql数据库基本配置、连接与增删改查相关操作技巧,需要的朋友可以参考下
    2023-04-04
  • Koa2中间件的作用及路由实现实例详解

    Koa2中间件的作用及路由实现实例详解

    这篇文章主要介绍了Koa2中间件的作用及路由实现实例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-05-05
  • 基于node.js之调试器详解

    基于node.js之调试器详解

    下面小编就为大家带来一篇基于node.js之调试器详解。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-08-08
  • 使用node.js搭建服务器

    使用node.js搭建服务器

    最近需要完成一个课程设计,被项目经理(组长)分配写界面功能,下面小编通过本文给大家分享使用使用node搭建小型服务器的方法,需要的朋友参考下
    2017-05-05
  • 详解在express站点中使用ejs模板引擎

    详解在express站点中使用ejs模板引擎

    本篇文章主要介绍了在express站点中使用ejs模板引擎,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-09-09
  • Node交互式的SFTP上传实现过程剖析

    Node交互式的SFTP上传实现过程剖析

    这篇文章主要为大家介绍了Node交互式的SFTP上传实现过程剖析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-08-08

最新评论