使用Node.js处理前端代码文件的编码问题

 更新时间:2016年02月16日 16:01:03   转载 投稿:goldensun  
这篇文章主要介绍了使用Node.js处理前端代码文件的编码问题的方法,Node自带的相关类库处理编码方面的问题时还是比较得心应手的,需要的朋友可以参考下

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

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');
}

相关文章

  • node实现登录图片验证码的示例代码

    node实现登录图片验证码的示例代码

    这篇文章主要介绍了node实现登录图片验证码的示例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-04-04
  • 深入理解nodejs搭建静态服务器(实现命令行)

    深入理解nodejs搭建静态服务器(实现命令行)

    这篇文章主要介绍了深入理解nodejs搭建静态服务器(实现命令行),小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2019-02-02
  • 深入分析node.js的异步API和其局限性

    深入分析node.js的异步API和其局限性

    这篇文章首先给大家介绍了为什么要用异步API,其次node.js异步api在使用过程有一些什么样的限制呢,对于这个问题我们下面来看看这篇关于node.js异步的介绍分析吧,有需要的可以参考借鉴。
    2016-09-09
  • 使用upstart把nodejs应用封装为系统服务实例

    使用upstart把nodejs应用封装为系统服务实例

    这篇文章主要介绍了使用upstart把nodejs应用封装为系统服务实例,需要的朋友可以参考下
    2014-06-06
  • Node.js设置CORS跨域请求中多域名白名单的方法

    Node.js设置CORS跨域请求中多域名白名单的方法

    这篇文章主要介绍了Node.js设置CORS跨域请求中多域名白名单的方法,文中通过示例代码介绍的非常详细,相信对大家具有一定的参考价值,需要的朋友们下面来一起看看吧。
    2017-03-03
  • nodejs简单抓包工具使用详解

    nodejs简单抓包工具使用详解

    这篇文章主要介绍了nodejs简单抓包工具使用详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-08-08
  • 从零学习node.js之模块规范(一)

    从零学习node.js之模块规范(一)

    Node.js是一个基于谷歌浏览器JavaScript执行环境建立的一个平台,让JavaScript可以脱离客户端浏览器运行,让 JavaScript具有服务器语言的能力。从本文开始我们进行学习node.js,这篇文章主要介绍的是node.js中模块规范的相关资料,需要的朋友可以参考下。
    2017-02-02
  • 用nodejs实现json和jsonp服务的方法

    用nodejs实现json和jsonp服务的方法

    本篇文章主要介绍了用nodejs实现json和jsonp服务的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-08-08
  • nodejs中全局变量的实例解析

    nodejs中全局变量的实例解析

    本文主要介绍了nodejs中全局变量的相关知识,具有很好的参考价值。下面跟着小编一起来看下吧
    2017-03-03
  • CentOS上安装Node.js和mongodb笔记

    CentOS上安装Node.js和mongodb笔记

    这篇文章主要介绍了CentOS上安装Node.js和mongodb笔记,本文讲解了Python安装、Node.js安装、npm安装、mongodb驱动安装、mongodb数据库操作测试代码等内容,需要的朋友可以参考下
    2015-04-04

最新评论