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

使用 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');
}
(0)

相关推荐

  • Nodejs中读取中文文件编码问题、发送邮件和定时任务实例

    关于nodejs读取中文文件真是折腾了不少时间,网上各种方案,最后没有一个适用我,好在解决了. 下面的三个知识点都是从项目中抽出的,要单独运行脚本的话需要用全局模式来安装模块,比如安装中文转换模块(后续其它的也需要这么做): 复制代码 代码如下: npm install -g iconv-lite npm install -g nodemailer npm install -g node-schedule 1.nodejs读取中文文件编码问题 准备一个文本文件(当然也可以是csv文件等)test

  • nodejs批量修改文件编码格式

    摘要: 最近在制作手册的时候遇到了一个问题'文档乱码',查看文件之后发现文件编码不对,总共100多个文件,如果用编辑器另存为utf8,那就悲催了.所以自己就写了个程序,批量修改文件编码格式. 代码: 复制代码 代码如下: /**  * 修改文件编码格式,例如:GBK转UTF8  * 支持多级目录  * @param {String} [root_path] [需要进行转码的文件路径]  * @param {Array}  [file_type] [需要进行转码的文件格式,比如html文件]  *

  • Node.js中使用Buffer编码、解码二进制数据详解

    JavaScript很擅长处理字符串,但是因为它最初的设计是用来处理HTML文档,因此它并不太擅长处理二进制数据.JavaScript没有byte类型,没有结构化的类型(structured types),甚至没有字节数组,只有数字和字符串.(原文:JavaScript doesn't have a byte type - it just has numbers - or structured types, or http://skylitecellars.com/ even byte arra

  • 详解nodejs爬虫程序解决gbk等中文编码问题

    使用nodejs写了一个爬虫的demo,目的是提取网页的title部分. 遇到最大的问题就是网页的编码与nodejs默认编码不一致造成的乱码问题.nodejs支持utf8, ucs2, ascii, binary, base64, hex等编码方式,但是对于汉语言来说编码主要分为三种,utf-8,gb2312,gbk.这里面gbk是完全兼容gb2312的,因此在处理编码的时候主要就分为utf-8以及gbk两大类.(这是在没有考虑到其他国家的编码情况,比如日本的Shift_JIS编码等,同时这里这

  • node.js学习之base64编码解码

    一. Base64编码由来 为什么会有Base64编码呢?因为有些网络传送渠道并不支持所有的字节,例如传统的邮件只支持可见字符的传送,像ASCII码的控制字符就 不能通过邮件传送.这样用途就受到了很大的限制,比如图片二进制流的每个字节不可能全部是可见字符,所以就传送不了.最好的方法就是在不改变传统协议的情 况下,做一种扩展方案来支持二进制文件的传送.把不可打印的字符也能用可打印字符来表示,问题就解决了.Base64编码应运而生,Base64就是一种 基于64个可打印字符来表示二进制数据的表示方法

  • Node.js编码规范

    调用函数的时候,函数名与左括号之间没有空格. 函数名与参数序列之间,没有空格:所有其他语法元素与左括号之间,都有一个空格. 使用小驼峰式命名法作为所有变量和属性的命名规则. 缩进使用两空格,统一使用单引号. 关联数组,除非键名中有空格或是非法字符,否则一律不用引号. 不要将不同目的的语句,合并成一行. 不要省略句末的分号,哪怕一行只有一个语句. 不要使用自增(++)和自减(--)运算符,用+=和-=代替. 不要使用"相等"(==)运算符,只使用"严格相等"(===)

  • nodejs爬虫抓取数据之编码问题

    cheerio DOM化并解析的时候 1.假如使用了 .text()方法,则一般不会有html实体编码的问题出现 2.如果使用了 .html()方法,则很多情况下(多数是非英文的时候)都会出现,这时,可能就需要转义一番了 类似这些 因为需要作数据存储,所有需要转换 复制代码 代码如下: Халк крушит. Новый способ исполнен 大多数都是&#(x)?\w+的格式 所以就用正则转换一番 var body = ....//这里就是请求后获得的返回数据,或者那些 .html

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

    使用 NodeJS 编写前端工具时,操作得最多的是文本文件,因此也就涉及到了文件编码的处理问题.我们常用的文本编码有 UTF8 和 GBK 两种,并且 UTF8 文件还可能带有 BOM.在读取不同编码的文本文件时,需要将文件内容转换为 JS 使用的 UTF8 编码字符串后才能正常处理. BOM 的移除 BOM 用于标记一个文本文件使用 Unicode 编码,其本身是一个 Unicode 字符("\uFEFF"),位于文本文件头部.在不同的 Unicode 编码下,BOM 字符对应的二进

  • Node.js查找当前目录下文件夹实例代码

    整理文档,搜刮出Node.js查找当前目录下文件夹实例代码,稍微整理精简一下做下分享. var http = require("http"); var fs = require("fs"); var server = http.createServer(function (req,res) { //不处理收藏夹小图标 if(req.url == "/favicon.ico"){ return; } //files是文件名的数组 表示text这个文

  • 使用node.js对音视频文件加密的实例代码

    废话不多说了,直接给大家贴代码了,具体代码如下所示: fs.readFile('./downsuccess/'+name+'', {flag: 'r+', encoding: ''}, function (err, data) { console.log('读取中') if(err) { return; } let b = new Buffer(data); let c = b.toString('hex'); let cipherBuffer = _this.cipher(data); fs.

  • Node.JS枚举统计当前文件夹和子目录下所有代码文件行数

    使用Node.JS的大多数用记事本开发,有时侯会需要统计工程代码量,然后记事本大部分没有这个功能.其实用node.js几行代码就可以实现. var path = require('path') var fs = require('fs') //需要统计的文件类型,可自己删减,均小写 var codesFiles = [ '.css', '.js', '.html', '.tmpl', '.part', '.json', '.md', '.txt', '.yml', '.java', '.cs',

  • 原生JS实现前端本地文件上传

    本文实例为大家分享了JS实现前端本地文件上传的具体代码,供大家参考,具体内容如下 通过input type = file来选择本地文件 <div> <form> <input type="file" id="file-input" name="fileContent"> </form> </div> var fileInput = document.querySelector('#fil

  • node.js express框架实现文件上传与下载功能实例详解

    本文实例讲述了node.js express框架实现文件上传与下载功能.分享给大家供大家参考,具体如下: 背景 昨天吉视传媒的客户对IPS信息发布系统又提了一个新需求,就是发布端发送消息时需要支持附件的上传,而接收端可以对发布端上传的附件进行下载:接收端回复消息时也需要支持上传附件,发布端可以对所有接收端上传的附件进行打包下载. 功能实现 前台部分 前台使用webUploader插件即可,这是百度开发的一款文件上传组件,具体使用查看它的API即可.这个项目之前开发的时候前台使用了angular.

  • node.js通过url读取文件

    本文实例为大家分享了node.js通过url读取文件的具体代码,供大家参考,具体内容如下 在浏览器地址栏中输入127.0.0.1:3000和127.0.0.1:3000/node时,读取node.html文件,输入127.0.0.1:3000/banner时读取banner.json文件 准备工作 首先我们在www的文件目录下新建两个文件,一个是node.htnl,一个是banner.json,并在文件中添加一点内容 1.新建01.js文件并导入模块 let fs = require("fs&q

  • Node.js path模块,获取文件后缀名操作

    我就废话不多说了,大家还是直接看代码吧~ demo.js: //path模块 var path=require('path'); /*nodejs自带的模块*/ var extname=path.extname("123.html"); //获取文件的后缀名 console.log(extname); 补充知识:node 的path模块中 path.resolve()和path.join()的区别 一.path模块的引入. 直接引用.node中自带的模块 const path = re

  • Node.js实现前端后端数据传输加密解密

    目录 一.简介 二.示例 2.1 生成公私钥对 2.2 公钥加密 2.3 私钥解密 三.总结 一.简介 在前后端通信过程中,一些敏感信息,特别是用户的账号密码,需要加密进行传输,如何选择加密方式也是一门学问,这里倒也不过多偏题了. 通常来说B/S架构中用的比较多的传输数据加密是RSA加密,核心思想就是公钥加密,私钥解密. 公钥,可以理解为可以公开的钥匙,服务器将公钥发给客户端,客户端用公钥对数据进行加密传输,服务器收到客户端传来的密文,再用自己的配对的私钥进行解密,即可获得原始的数据. 大致流程

  • Node.js 中判断一个文件是否存在

    记录一些 Node.js 应用中的小知识点,如果你 Google/Baidu "Node.js 如何判断文件是否存在" 发现给出的很多答案还是使用的 fs.exists,这里不推荐使用 fs.exists 你可以选择 fs.stat 或 fs.access. 为什么不推荐 fs.exists 我们在设计一个回调函数时,通常会遵循一个原则 " 错误优先的回调函数",也就是返回值的第一个参数为错误信息,用以验证是否出错,其它的参数则用于返回数据. 如下所示为 fs.ex

随机推荐