来自 Web前端 2020-05-07 05:42 的文章
当前位置: 网上澳门金莎娱乐 > Web前端 > 正文

Node.js 指南

时间: 2019-09-06阅读: 154标签: 指南概述

JavaScript 语言自身只有字符串数据类型,没有二进制数据类型。

但在处理像TCP流或文件流时,必须使用到二进制数据。因此在 Node.js中,定义了一个 Buffer 类,该类用来创建一个专门存放二进制数据的缓存区。

在 Node.js 中,Buffer 类是随 Node 内核一起发布的核心库。Buffer 库为 Node.js 带来了一种存储原始数据的方法,可以让 Node.js 处理二进制数据,每当需要在 Node.js 中处理I/O操作中移动的数据时,就有可能使用 Buffer 库。原始数据存储在 Buffer 类的实例中。一个 Buffer 类似于一个整数数组,但它对应于 V8 堆内存之外的一块原始内存。

在v6.0之前创建Buffer对象直接使用new Buffer()构造函数来创建对象实例,但是Buffer对内存的权限操作相比很大,可以直接捕获一些敏感信息,所以在v6.0以后,官方文档里面建议使用  class="marked">Buffer.from() 接口去创建Buffer对象。


本指南介绍了如何迁移到安全的Buffer构造函数方法,迁移修复了以下弃用警告:

Buffer 与字符编码

Buffer 实例一般用于表示编码字符的序列,比如 UTF-8 、 UCS2 、 Base64 、或十六进制编码的数据。 通过使用显式的字符编码,就可以在 Buffer 实例与普通的 JavaScript 字符串之间进行相互转换。

const buf = Buffer.from('runoob', 'ascii');

// 输出 72756e6f6f62
console.log(buf.toString('hex'));

// 输出 cnVub29i
console.log(buf.toString('base64'));

Node.js 目前支持的字符编码包括:

  • ascii - 仅支持 7 位 ASCII 数据。如果设置去掉高位的话,这种编码是非常快的。

  • utf8 - 多字节编码的 Unicode 字符。许多网页和其他文档格式都使用 UTF-8 。

  • utf16le - 2 或 4 个字节,小字节序编码的 Unicode 字符。支持代理对(U+10000 至 U+10FFFF)。

  • ucs2 - utf16le 的别名。

  • base64 - Base64 编码。

  • latin1 - 一种把 Buffer 编码成一字节编码的字符串的方式。

  • binary - latin1 的别名。

  • hex - 将每个字节编码为两个十六进制字符。


由于安全性和可用性问题,不建议使用Buffer()和new Buffer()构造函数,请改用new Buffer.alloc()、Buffer.allocUnsafe()或Buffer.from()构造方法。变式1:放弃对Node.js ≤4.4.x和5.0.0 - 5.9.x的支持(推荐)。变式2:使用polyfill。变式3:手动检测,带有安全措施。使用grep查找有问题的代码位

创建 Buffer 类

Buffer 提供了以下 API 来创建 Buffer 类:

  • Buffer.alloc(size[, fill[, encoding]]): 返回一个指定大小的 Buffer 实例,如果没有设置 fill,则默认填满 0
  • Buffer.allocUnsafe(size): 返回一个指定大小的 Buffer 实例,但是它不会被初始化,所以它可能包含敏感的数据
  • Buffer.allocUnsafeSlow(size)
  • Buffer.from(array): 返回一个被 array 的值初始化的新的 Buffer 实例(传入的 array 的元素只能是数字,不然就会自动被 0 覆盖)
  • Buffer.from(arrayBuffer[, byteOffset[, length]]): 返回一个新建的与给定的 ArrayBuffer 共享同一内存的 Buffer。
  • Buffer.from(buffer): 复制传入的 Buffer 实例的数据,并返回一个新的 Buffer 实例
  • Buffer.from(string[, encoding]): 返回一个被 string 的值初始化的新的 Buffer 实例
// 创建一个长度为 10、且用 0 填充的 Buffer。
const buf1 = Buffer.alloc(10);

// 创建一个长度为 10、且用 0x1 填充的 Buffer。 
const buf2 = Buffer.alloc(10, 1);

// 创建一个长度为 10、且未初始化的 Buffer。
// 这个方法比调用 Buffer.alloc() 更快,
// 但返回的 Buffer 实例可能包含旧数据,
// 因此需要使用 fill() 或 write() 重写。
const buf3 = Buffer.allocUnsafe(10);

// 创建一个包含 [0x1, 0x2, 0x3] 的 Buffer。
const buf4 = Buffer.from([1, 2, 3]);

// 创建一个包含 UTF-8 字节 [0x74, 0xc3, 0xa9, 0x73, 0x74] 的 Buffer。
const buf5 = Buffer.from('tést');

// 创建一个包含 Latin-1 字节 [0x74, 0xe9, 0x73, 0x74] 的 Buffer。
const buf6 = Buffer.from('tést', 'latin1');

只需运行grep -nrE '[^a-zA-Z](Slow)?Buffers*(' --exclude-dir node_modules。

写入缓冲区

它会在你自己的代码中找到所有可能不安全的地方(有一些不太常见的例外)。

语法

写入 Node 缓冲区的语法如下所示:

buf.write(string[, offset[, length]][, encoding])

使用Node.js 8查找有问题的代码位

参数

参数描述如下:

  • string - 写入缓冲区的字符串。

  • offset - 缓冲区开始写入的索引值,默认为 0 。

  • length - 写入的字节数,默认为 buffer.length

  • encoding - 使用的编码。默认为 'utf8' 。

根据 encoding 的字符编码写入 string 到 buf 中的 offset 位置。 length 参数是写入的字节数。 如果 buf 没有足够的空间保存整个字符串,则只会写入 string 的一部分。 只部分解码的字符不会被写入。

如果你使用的是Node.js ≥ 8.0.0(推荐使用),Node.js会公开多个选项,以帮助你找到相关的代码片段:

返回值

返回实际写入的大小。如果 buffer 空间不足, 则只会写入部分字符串。

--trace-warnings将使Node.js显示此警告的堆栈跟踪以及Node.js打印的其他警告。--trace-deprecation执行相同的操作,但仅适用于弃用警告。--pending-deprecation将显示更多类型的弃用警告,特别是,它也会显示Buffer()弃用警告,即使在Node.js 8上。

实例

buf = Buffer.alloc(256);
len = buf.write("www.runoob.com");

console.log("写入字节数 : "+  len);

执行以上代码,输出结果为:

$node main.js
写入字节数 : 14

你可以使用环境变量设置这些标志:

从缓冲区读取数据

$ export NODE_OPTIONS='--trace-warnings --pending-deprecation'$ cat example.js'use strict';const foo = new Buffer('foo');$ node example.js(node:7147) [DEP0005] DeprecationWarning: The Buffer() and new Buffer() constructors are not recommended for use due to security and usability concerns. Please use the new Buffer.alloc(), Buffer.allocUnsafe(), or Buffer.from() construction methods instead. at showFlaggedDeprecation (buffer.js:127:13) at new Buffer (buffer.js:148:3) at Object.lt;anonymousgt; (/path/to/example.js:2:13) [... more stack trace lines ...]

语法

读取 Node 缓冲区数据的语法如下所示:

buf.toString([encoding[, start[, end]]])

使用linters查找有问题的代码位

参数

参数描述如下:

  • encoding - 使用的编码。默认为 'utf8' 。

  • start - 指定开始读取的索引位置,默认为 0。

  • end - 结束位置,默认为缓冲区的末尾。

ESLint规则no-buffer-constructor或node/no-deprecated-api也查找对不推荐使用的Buffer()API的调用,这些规则包含在一些预设中。

返回值

解码缓冲区数据并使用指定的编码返回字符串。

但是有一个缺点,当Buffer被重写时,它并不总是正确工作,例如使用polyfill,因此建议将此与上述其他方法结合使用。

实例

buf = Buffer.alloc(26);
for (var i = 0 ; i < 26 ; i++) {
  buf[i] = i + 97;
}

console.log( buf.toString('ascii'));       // 输出: abcdefghijklmnopqrstuvwxyz
console.log( buf.toString('ascii',0,5));   // 输出: abcde
console.log( buf.toString('utf8',0,5));    // 输出: abcde
console.log( buf.toString(undefined,0,5)); // 使用 'utf8' 编码, 并输出: abcde

执行以上代码,输出结果为:

$ node main.js
abcdefghijklmnopqrstuvwxyz
abcde
abcde
abcde

变式1:放弃对Node.js ≤4.4.x和5.0.0 - 5.9.x的支持

将 Buffer 转换为 JSON 对象

这是目前推荐的解决方案,仅意味着最小的开销。

语法

将 Node Buffer 转换为 JSON 对象的函数语法格式如下:

buf.toJSON()

自2016年7月以来,Node.js 5.x版本系列一直未得到支持,并且Node.js 4.x版本系列在2018年4月达到其生命周期结束(→计划)。

返回值

返回 JSON 对象。

这意味着即使出现安全问题,这些版本的Node.js也不会收到任何更新,因此如果可能的话,应该避免使用这些版本线。

实例

var buf = Buffer.from('www.runoob.com');
var json = buf.toJSON(buf);

console.log(json);

执行以上代码,输出结果为:

{ type: 'Buffer',
  data: [ 119, 119, 119, 46, 114, 117, 110, 111, 111, 98, 46, 99, 111, 109 ] }

在这种情况下,你要做的是将所有new Buffer()或Buffer()调用转换为使用Buffer.alloc()或Buffer.from(),方法如下:

缓冲区合并

对于new Buffer(number),将其替换为Buffer.alloc(number)。

语法

Node 缓冲区合并的语法如下所示:

Buffer.concat(list[, totalLength])

对于new Buffer(string)(或new Buffer(string, encoding)),将其替换为Buffer.from(string)(或Buffer.from(string, encoding))。对于所有其他参数组合(这些更为罕见),还要用Buffer.from(...arguments)替换new Buffer(...arguments)。

参数

参数描述如下:

  • list - 用于合并的 Buffer 对象数组列表。

  • totalLength - 指定合并后Buffer对象的总长度。

请注意,Buffer.alloc()在当前Node.js版本上的速度也比new Buffer(size).fill(0)快,这是你需要确保零​​填充的原因。

返回值

返回一个多个成员合并的新 Buffer 对象。

建议启用ESLint规则no-buffer-constructor或node/no-deprecated-api以避免意外的不安全BufferAPI使用。

实例

var buffer1 = Buffer.from(('菜鸟教程'));
var buffer2 = Buffer.from(('www.runoob.com'));
var buffer3 = Buffer.concat([buffer1,buffer2]);
console.log("buffer3 内容: " + buffer3.toString());

执行以上代码,输出结果为:

buffer3 内容: 菜鸟教程 www.runoob.com

还有一个JSCodeshift codemod,用于自动将Buffer构造函数迁移到Buffer.alloc()或Buffer.from(),请注意,它目前仅适用于参数为文字或使用两个参数调用构造函数的情况。

缓冲区比较

如果你当前支持那些较旧的Node.js版本并且无法删除对它们的支持,或者如果你支持包的旧分支,考虑在较旧的分支上使用变式2或变式3,因此使用这些旧分支的人也将收到修复。这样,你将消除由不谨慎的BufferAPI使用引起的潜在问题,并且在Node.js 10上运行代码时,你的用户将不会观察到运行时弃用警告。

语法

Node Buffer 比较的函数语法如下所示, 该方法在 Node.js v0.12.2 版本引入:

buf.compare(otherBuffer);

变式2:使用polyfill

参数

参数描述如下:

  • otherBuffer - 与 buf 对象比较的另外一个 Buffer 对象。

本文由网上澳门金莎娱乐发布于Web前端,转载请注明出处:Node.js 指南

关键词: