一、全局对象
JavaScript 中有一个特殊的对象,称为全局对象(Global Object),它及其所有属性都可以在程序的任何地方访问,即全局变量。
在浏览器 JavaScript 中,通常 window 是全局对象, 而 Node.js 中的全局对象是 global,所有全局变量(除了 global 本身以外)都是 global 对象的属性。
在 Node.js 我们可以直接访问到 global 的属性,而不需要在应用中包含它。
1.1 全局对象与全局变量
global 最根本的作用是作为全局变量的宿主。按照 ECMAScript 的定义,满足以下条 件的变量是全局变量:
** 在最外层定义的变量 **;
** 全局对象的属性 **
** 隐式定义的变量(未定义直接赋值的变量) **
当你定义一个全局变量时,这个变量同时也会成为全局对象的属性,反之亦然。需要注 意的是,在 Node.js 中你不可能在最外层定义变量,因为所有用户代码都是属于当前模块的, 而模块本身不是最外层上下文。
注意
: 最好不要使用 var 定义变量以避免引入全局变量,因为全局变量会污染命名空间,提高代码的耦合风险。
1.2 __filename
__filename 表示当前正在执行的脚本的文件名。它将输出文件所在位置的绝对路径,且和命令行参数所指定的文件名不一定相同。 如果在模块中,返回的值是模块文件的路径。
实例
创建文件 global1.js ,代码如下所示:
1 | // 输出全局变量 __filename 的值 |
执行 global1.js 文件,结果如下所示:
E:\workspace\workspace(nodejs)\day03\global1.js
1.3 __dirname
__dirname 表示当前执行脚本所在的目录。
实例
修改文件 global1.js ,代码如下所示:
1 | // 输出全局变量 __dirname 的值 |
执行 global1.js 文件,结果如下所示:
E:\workspace\workspace(nodejs)\day03
1.4 setTimeout(cb, ms)
setTimeout(cb, ms) 全局函数在指定的毫秒(ms)数后执行指定函数(cb)。:setTimeout() 只执行一次指定函数。
返回一个代表定时器的句柄值。
实例
修改文件 global1.js ,代码如下所示:
1 | function printHello(){ |
执行 global1.js 文件,结果如下所示:
Hello, World!
Hello, World!
Hello, World!
Hello, World!
Hello, World!
1.5 clearTimeout(t)
clearTimeout( t ) 全局函数用于停止一个之前通过 setTimeout() 创建的定时器。 参数 t 是通过 setTimeout() 函数创建的定时器。
实例
修改文件 global1.js ,代码如下所示:
1 | function printHello(){ |
执行 global1.js 文件,结果没有输出。
1.6 setInterval(cb, ms)
setInterval(cb, ms) 全局函数在指定的毫秒(ms)数后执行指定函数(cb)。
返回一个代表定时器的句柄值。可以使用 clearInterval(t) 函数来清除定时器。
setInterval() 方法会不停地调用函数,直到 clearInterval() 被调用或窗口被关闭。
实例
修改文件 global1.js ,代码如下所示:
1 | function printHello(){ |
执行 global1.js 文件,结果如下所示:
Hello, World!
Hello, World!
Hello, World!
Hello, World!
Hello, World!
1.7 console
console 用于提供控制台标准输出,它是由 Internet Explorer 的 JScript 引擎提供的调试工具,后来逐渐成为浏览器的实施标准。
Node.js 沿用了这个标准,提供与习惯行为一致的 console 对象,用于向标准输出流(stdout)或标准错误流(stderr)输出字符。
方法 | 描述 |
---|---|
console.log([data][, ...]) | 向标准输出流打印字符并以换行符结束。该方法接收若干 个参数,如果只有一个参数,则输出这个参数的字符串形式。如果有多个参数,则 以类似于C 语言 printf() 命令的格式输出。 |
console.info([data][, ...]) | 该命令的作用是返回信息性消息,这个命令与console.log差别并不大,除了在chrome中只会输出文字外,其余的会显示一个蓝色的惊叹号。 |
console.error([data][, ...]) | 输出错误消息的。控制台在出现错误时会显示是红色的叉子。 |
console.warn([data][, ...]) | 输出警告消息。控制台出现有黄色的惊叹号。 |
console.dir(obj[, options]) | 用来对一个对象进行检查(inspect),并以易于阅读和打印的格式显示。 |
console.time(label) | 输出时间,表示计时开始。 |
console.timeEnd(label) | 结束时间,表示计时结束。 |
console.trace(message[, ...]) | 当前执行的代码在堆栈中的调用路径,这个测试函数运行很有帮助,只要给想测试的函数里面加入 console.trace 就行了。 |
console.assert(value[, message][, ...]) | 用于判断某个表达式或变量是否为真,接收两个参数,第一个参数是表达式,第二个参数是字符串。只有当第一个参数为false,才会输出第二个参数,否则不会有任何结果。 |
console.log():向标准输出流打印字符并以换行符结束。
console.log 接收若干 个参数,如果只有一个参数,则输出这个参数的字符串形式。如果有多个参数,则 以类似于C 语言 printf() 命令的格式输出。
第一个参数是一个字符串,如果没有 参数,只打印一个换行。
1 | console.log('Hello world'); |
运行结果为:
Hello world
byvoid%diovyb
byvoid1991iovyb
console.error():与console.log() 用法相同,只是向标准错误流输出。
console.trace():向标准错误流输出当前的调用栈。
1 | console.trace(); |
运行结果为:
Trace
at Object.(E:\workspace\workspace(nodejs)\day03\consolel.js:5:9)
at Module._compile (internal/modules/cjs/loader.js:1063:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1092:10)
at Module.load (internal/modules/cjs/loader.js:928:32)
at Function.Module._load (internal/modules/cjs/loader.js:769:14)
at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:72:12)
at internal/main/run_main_module.js:17:47
实例
创建文件 console1.js ,代码如下所示:
1 | console.info("程序开始执行:"); |
执行 console1.js 文件,结果如下所示:
程序开始执行:
计数: 10
获取数据: 0.125ms
程序执行完毕。
1.8 process
process 是一个全局变量,即 global 对象的属性。
它用于描述当前Node.js 进程状态的对象,提供了一个与操作系统的简单接口。通常在你写本地命令行程序的时候,少不了要 和它打交道。下面将会介绍 process 对象的一些最常用的成员方法。
事件 | 描述 |
---|---|
exit | 当进程准备退出时触发。 |
beforeExit | 当 node 清空事件循环,并且没有其他安排时触发这个事件。通常来说,当没有进程安排时 node 退出,但是 'beforeExit' 的监听器可以异步调用,这样 node 就会继续执行。 |
uncaughtException | 当一个异常冒泡回到事件循环,触发这个事件。如果给异常添加了监视器,默认的操作(打印堆栈跟踪信息并退出)就不会发生。 |
Signal 事件 | 当进程接收到信号时就触发。信号列表详见标准的 POSIX 信号名,如 SIGINT、SIGUSR1 等。 |
实例
创建文件 process.js ,代码如下所示:
1 | process.on('exit', function(code) { |
执行 process.js 文件,代码如下所示:
程序执行结束
退出码为: 0
退出状态码
退出状态码如下所示:
名称 | 描述 |
---|---|
Uncaught Fatal Exception | 有未捕获异常,并且没有被域或 uncaughtException 处理函数处理。 |
Unused | 保留 |
Internal JavaScript Parse Error | JavaScript的源码启动 Node 进程时引起解析错误。非常罕见,仅会在开发 Node 时才会有。 |
Internal JavaScript Evaluation Failure | JavaScript 的源码启动 Node 进程,评估时返回函数失败。非常罕见,仅会在开发 Node 时才会有。 |
Fatal Error | V8 里致命的不可恢复的错误。通常会打印到 stderr ,内容为: FATAL ERROR |
Non-function Internal Exception Handler | 未捕获异常,内部异常处理函数不知为何设置为on-function,并且不能被调用。 |
Internal Exception Handler Run-Time Failure | 未捕获的异常, 并且异常处理函数处理时自己抛出了异常。例如,如果 process.on('uncaughtException') 或 domain.on('error') 抛出了异常。 |
Unused | 保留 |
Invalid Argument | 可能是给了未知的参数,或者给的参数没有值。 |
Internal JavaScript Run-Time Failure | JavaScript的源码启动 Node 进程时抛出错误,非常罕见,仅会在开发 Node 时才会有。 |
Invalid Debug Argument | 设置了参数--debug 和/或 --debug-brk,但是选择了错误端口。 |
Signal Exits | 如果 Node 接收到致命信号,比如SIGKILL 或 SIGHUP,那么退出代码就是128 加信号代码。这是标准的 Unix 做法,退出信号代码放在高位。 |
Process 属性
Process 提供了很多有用的属性,便于我们更好的控制系统的交互:
属性 | 描述 |
---|---|
stdout | 标准输出流。 |
stderr | 标准错误流。 |
stdin | 标准输入流。 |
argv | argv 属性返回一个数组,由命令行执行脚本时的各个参数组成。它的第一个成员总是node,第二个成员是脚本文件名,其余成员是脚本文件的参数。 |
execPath | 返回执行当前脚本的 Node 二进制文件的绝对路径。 |
execArgv | 返回一个数组,成员是命令行下执行脚本时,在Node可执行文件与脚本文件之间的命令行参数。 |
env | 返回一个对象,成员为当前 shell 的环境变量 |
exitCode | 进程退出时的代码,如果进程优通过 process.exit() 退出,不需要指定退出码。 |
version | Node 的版本,比如v0.10.18。 |
versions | 一个属性,包含了 node 的版本和依赖. |
config | 一个包含用来编译当前 node 执行文件的 javascript 配置选项的对象。它与运行 ./configure 脚本生成的 "config.gypi" 文件相同。 |
pid | 当前进程的进程号。 |
title | 进程名,默认值为"node",可以自定义该值。 |
arch | 当前 CPU 的架构:'arm'、'ia32' 或者 'x64'。 |
platform | 运行程序所在的平台系统 'darwin', 'freebsd', 'linux', 'sunos' 或 'win32' |
mainModule | require.main 的备选方法。不同点,如果主模块在运行时改变,require.main可能会继续返回老的模块。可以认为,这两者引用了同一个模块。 |
实例
修改文件 process.js ,代码如下所示:
1 | // 输出到终端 |
执行 process.js 文件,结果如下所示:
Hello World!
0: E:\Program\node-v14.13.1\node.exe
1: E:\workspace\workspace(nodejs)\day03\process.js
E:\Program\node-v14.13.1\node.exe
win32
方法参考手册
Process 提供了很多有用的方法,便于我们更好的控制系统的交互:
方法 | 描述 |
---|---|
abort() | 这将导致 node 触发 abort 事件。会让 node 退出并生成一个核心文件。 |
chdir(directory) | 改变当前工作进程的目录,如果操作失败抛出异常。 |
cwd() | 返回当前进程的工作目录 |
exit([code]) | 使用指定的 code 结束进程。如果忽略,将会使用 code 0。 |
getgid() | 获取进程的群组标识(参见 getgid(2))。获取到得时群组的数字 id,而不是名字。注意 :这个函数仅在 POSIX 平台上可用(例如,非Windows 和 Android)。 |
setgid(id) | 设置进程的群组标识(参见 setgid(2))。可以接收数字 ID 或者群组名。如果指定了群组名,会阻塞等待解析为数字 ID 。注意 :这个函数仅在 POSIX 平台上可用(例如,非Windows 和 Android)。 |
getuid() | 获取进程的用户标识(参见 getuid(2))。这是数字的用户 id,不是用户名。注意 :这个函数仅在 POSIX 平台上可用(例如,非Windows 和 Android)。 |
setuid(id) | 设置进程的用户标识(参见setuid(2))。接收数字 ID或字符串名字。果指定了群组名,会阻塞等待解析为数字 ID 。注意 :这个函数仅在 POSIX 平台上可用(例如,非Windows 和 Android)。 |
getgroups() | 返回进程的群组 iD 数组。POSIX 系统没有保证一定有,但是 node.js 保证有。注意 :这个函数仅在 POSIX 平台上可用(例如,非Windows 和 Android)。 |
setgroups(groups) | 设置进程的群组 ID。这是授权操作,所以你需要有 root 权限,或者有 CAP_SETGID 能力。注意 :这个函数仅在 POSIX 平台上可用(例如,非Windows 和 Android)。 |
initgroups(user, extra_group) | 读取 /etc/group ,并初始化群组访问列表,使用成员所在的所有群组。这是授权操作,所以你需要有 root 权限,或者有 CAP_SETGID 能力。注意 :这个函数仅在 POSIX 平台上可用(例如,非Windows 和 Android)。 |
kill(pid[, signal]) | 发送信号给进程. pid 是进程id,并且 signal 是发送的信号的字符串描述。信号名是字符串,比如 'SIGINT' 或 'SIGHUP'。如果忽略,信号会是 'SIGTERM'。 |
memoryUsage() | 返回一个对象,描述了 Node 进程所用的内存状况,单位为字节。 |
nextTick(callback) | 一旦当前事件循环结束,调用回调函数。 |
umask([mask]) | 设置或读取进程文件的掩码。子进程从父进程继承掩码。如果mask 参数有效,返回旧的掩码。否则,返回当前掩码。 |
uptime() | 返回 Node 已经运行的秒数。 |
hrtime() | 返回当前进程的高分辨时间,形式为 [seconds, nanoseconds]数组。它是相对于过去的任意事件。该值与日期无关,因此不受时钟漂移的影响。主要用途是可以通过精确的时间间隔,来衡量程序的性能。你可以将之前的结果传递给当前的 process.hrtime() ,会返回两者间的时间差,用来基准和测量时间间隔。 |
实例
修改文件 process.js ,代码如下所示:
1 | // 输出当前目录 |
执行 process.js 文件,结果如下所示:
当前目录: E:\workspace\workspace(nodejs)\day03
当前版本: v14.13.1
{
rss: 19464192,
heapTotal: 4726784,
heapUsed: 2911608,
external: 1031529,
arrayBuffers: 9386
}
二、常用工具
util 是一个Node.js 核心模块,提供常用函数的集合,用于弥补核心 JavaScript 的功能 过于精简的不足。
使用方法如下:
1 | const util = require('util'); |
2.1 util.callbackify
util.callbackify(original) 将 async 异步函数(或者一个返回值为 Promise 的函数)转换成遵循异常优先的回调风格的函数,例如将 (err, value) => ... 回调作为最后一个参数。 在回调函数中,第一个参数为拒绝的原因(如果 Promise 解决,则为 null),第二个参数则是解决的值。
实例
创建文件 util1.js ,代码如下所示:
1 | const util = require('util'); |
以上代码输出结果为:
hello world
回调函数是异步执行的,并且有异常堆栈错误追踪。 如果回调函数抛出一个异常,进程会触发一个 'uncaughtException' 异常,如果没有被捕获,进程将会退出。
null 在回调函数中作为一个参数有其特殊的意义,如果回调函数的首个参数为 Promise 拒绝的原因且带有返回值,且值可以转换成布尔值 false,这个值会被封装在 Error 对象里,可以通过属性 reason 获取。
original 为 async 异步函数。该函数返回传统回调函数。
2.2 util.inherits
util.inherits(constructor, superConstructor) 是一个实现对象间原型继承的函数。
JavaScript 的面向对象特性是基于原型的,与常见的基于类的不同。JavaScript 没有提供对象继承的语言级别特性,而是通过原型复制来实现的。
在这里我们只介绍 util.inherits 的用法,示例如下:
1 | var util = require('util'); |
我们定义了一个基础对象 Base 和一个继承自 Base 的 Sub,Base 有三个在构造函数内定义的属性和一个原型中定义的函数,通过util.inherits 实现继承。运行结果如下:
base
Hello base
Base { name: 'base', base: 1991, sayHello: [Function (anonymous)] }
sub
Sub { name: 'sub' }
注意
:Sub 仅仅继承了Base 在原型中定义的函数,而构造函数内部创造的 base 属 性和 sayHello 函数都没有被 Sub 继承。
同时,在原型中定义的属性不会被 console.log 作 为对象的属性输出。如果我们去掉 objSub.sayHello(); 这行的注释,将会看到:
1 | base |
2.3 util.inspect
util.inspect(object,[showHidden],[depth],[colors]) 是一个将任意对象转换 为字符串的方法,通常用于调试和错误输出。它至少接受一个参数 object,即要转换的对象。
showHidden 是一个可选参数,如果值为 true,将会输出更多隐藏信息。
depth 表示最大递归的层数,如果对象很复杂,你可以指定层数以控制输出信息的多 少。如果不指定depth,默认会递归 2 层,指定为 null 表示将不限递归层数完整遍历对象。 如果 colors 值为 true,输出格式将会以 ANSI 颜色编码,通常用于在终端显示更漂亮 的效果。
特别要指出的是,util.inspect 并不会简单地直接把对象转换为字符串,即使该对 象定义了 toString 方法也不会调用。
1 | var util = require('util'); |
运行结果是:
1 | Person { name: 'byvoid', toString: [Function (anonymous)] } |
2.4 util.isArray(object)
如果给定的参数 "object" 是一个数组返回 true,否则返回 false。
1 | var util = require('util'); |
2.5 util.isRegExp(object)
如果给定的参数 "object" 是一个正则表达式返回true,否则返回false。
1 | var util = require('util'); |
2.6 util.isDate(object)
如果给定的参数 "object" 是一个日期返回true,否则返回false。
1 | var util = require('util'); |
更多详情可以访问 http://nodejs.org/api/util.html 了解详细内容。
三、文件系统
Node.js 提供一组类似 UNIX(POSIX)标准的文件操作API。 Node 导入文件系统模块(fs)语法如下所示:
1 | var fs = require("fs") |
3.1 异步和同步
Node.js 文件系统(fs 模块)模块中的方法均有异步和同步版本,例如读取文件内容的函数有异步的 fs.readFile() 和同步的 fs.readFileSync()。
异步的方法函数最后一个参数为回调函数,回调函数的第一个参数包含了错误信息(error)。
建议大家使用异步方法,比起同步,异步方法性能更高,速度更快,而且没有阻塞。
实例
创建 input.txt 文件,内容如下:
1 | Node.js 提供一组类似 UNIX(POSIX)标准的文件操作API。 |
创建 file.js 文件, 代码如下:
1 | var fs = require("fs"); |
以上代码执行结果如下:
同步读取: Node.js 提供一组类似 UNIX(POSIX)标准的文件操作API。
程序执行完毕。
异步读取: Node.js 提供一组类似 UNIX(POSIX)标准的文件操作API。
接下来,让我们来具体了解下 Node.js 文件系统的方法。
3.2 打开文件
语法
fs.open(path, flags[, mode], callback)
参数
参数使用说明如下:
path - 文件的路径。
flags - 文件打开的行为。具体值详见下文。
mode - 设置文件模式(权限),文件创建默认权限为 0666(可读,可写)。
callback - 回调函数,带有两个参数如:callback(err, fd)。
flags 参数可以是以下值:
Flag | 描述 |
---|---|
r | 以读取模式打开文件。如果文件不存在抛出异常。 |
r+ | 以读写模式打开文件。如果文件不存在抛出异常。 |
rs | 以同步的方式读取文件。 |
rs+ | 以同步的方式读取和写入文件。 |
w | 以写入模式打开文件,如果文件不存在则创建。 |
wx | 类似 'w',但是如果文件路径存在,则文件写入失败。 |
w+ | 以读写模式打开文件,如果文件不存在则创建。 |
wx+ | 类似 'w+', 但是如果文件路径存在,则文件读写失败。 |
a | 以追加模式打开文件,如果文件不存在则创建。 |
ax | 类似 'a', 但是如果文件路径存在,则文件追加失败。 |
a+ | 以读取追加模式打开文件,如果文件不存在则创建。 |
ax+ | 类似 'a+', 但是如果文件路径存在,则文件读取追加失败。 |
实例
接下来我们创建 file.js 文件,并打开 input.txt 文件进行读写,代码如下所示:
1 | var fs = require("fs"); |
以上代码执行结果如下:
准备打开文件!
文件打开成功!
3.3 获取文件信息
语法
fs.stat(path, callback)
参数
参数使用说明如下:
path - 文件路径。
callback - 回调函数,带有两个参数如:(err, stats), stats 是 fs.Stats 对象。
fs.stat(path)执行后,会将stats类的实例返回给其回调函数。可以通过stats类中的提供方法判断文件的相关属性。例如判断是否为文件:
1 | var fs = require('fs'); |
stats类中的方法有:
方法 | 描述 |
---|---|
stats.isFile() | 如果是文件返回 true,否则返回 false。 |
stats.isDirectory() | 如果是目录返回 true,否则返回 false。 |
stats.isBlockDevice() | 如果是块设备返回 true,否则返回 false。 |
stats.isCharacterDevice() | 如果是字符设备返回 true,否则返回 false。 |
stats.isSymbolicLink() | 如果是软链接返回 true,否则返回 false。 |
stats.isFIFO() | 如果是FIFO,返回true,否则返回 false。FIFO是UNIX中的一种特殊类型的命令管道。 |
stats.isSocket() | 如果是 Socket 返回 true,否则返回 false。 |
实例
接下来我们修改 file.js 文件,代码如下所示:
1 | var fs = require("fs"); |
以上代码执行结果如下:
准备打开文件!
Stats {
dev: 2093865975,
mode: 33206,
nlink: 1,
uid: 0,
gid: 0,
rdev: 0,
blksize: 4096,
ino: 1688849860584246,
size: 69,
blocks: 0,
atimeMs: 1602752855007.6714,
mtimeMs: 1602752855007.6714,
ctimeMs: 1602752855007.6714,
birthtimeMs: 1602752835675.5398,
atime: 2020-10-15T09:07:35.008Z,
mtime: 2020-10-15T09:07:35.008Z,
ctime: 2020-10-15T09:07:35.008Z,
birthtime: 2020-10-15T09:07:15.676Z
}
读取文件信息成功!
是否为文件(isFile) ? true
是否为目录(isDirectory) ? false
3.4 写入文件
语法
fs.writeFile(file, data[, options], callback)
writeFile 直接打开文件默认是 w 模式,所以如果文件存在,该方法写入的内容会覆盖旧的文件内容。
参数
参数使用说明如下:
file - 文件名或文件描述符。
data - 要写入文件的数据,可以是 String(字符串) 或 Buffer(缓冲) 对象。
options - 该参数是一个对象,包含 {encoding, mode, flag}。默认编码为 utf8, 模式为 0666 , flag 为 'w'
callback - 回调函数,回调函数只包含错误信息参数(err),在写入失败时返回。
实例
接下来我们修改 file.js 文件,代码如下所示:
1 | var fs = require("fs"); |
以上代码执行结果如下:
准备写入文件
数据写入成功!
--------我是分割线-------------
读取写入的数据!
异步读取文件数据: 我是通 过fs.writeFile 写入文件的内容
3.5 读取文件
语法
fs.read(fd, buffer, offset, length, position, callback)
该方法使用了文件描述符来读取文件。
参数
参数使用说明如下:
fd - 通过 fs.open() 方法返回的文件描述符。
buffer - 数据写入的缓冲区。
offset - 缓冲区写入的写入偏移量。
length - 要从文件中读取的字节数。
position - 文件读取的起始位置,如果 position 的值为 null,则会从当前文件指针的位置读取。
callback - 回调函数,有三个参数err, bytesRead, buffer,err 为错误信息, bytesRead 表示读取的字节数,buffer 为缓冲区对象。
实例
接下来我们修改 file.js 文件,代码如下所示:
1 | var fs = require("fs"); |
以上代码执行结果如下:
准备打开已存在的文件!
文件打开成功!
准备读取文件:
47 字节被读取
我是通 过fs.writeFile 写入文件的内容
3.6 关闭文件
语法
fs.close(fd, callback)
该方法为异步模式下关闭文件的语法格式,使用了文件描述符来读取文件。
参数
参数使用说明如下:
fd - 通过 fs.open() 方法返回的文件描述符。
callback - 回调函数,没有参数。
实例
接下来我们修改 file.js 文件,代码如下所示:
1 | var fs = require("fs"); |
以上代码执行结果如下:
准备打开文件!
文件打开成功!
准备读取文件!
我是通 过fs.writeFile 写入文件的内容
文件关闭成功
3.7 截取文件
语法
fs.ftruncate(fd, len, callback)
该方法为异步模式下截取文件的语法格式,使用了文件描述符来读取文件。
参数
参数使用说明如下:
fd - 通过 fs.open() 方法返回的文件描述符。
len - 文件内容截取的长度。
callback - 回调函数,没有参数。
实例
接下来我们修改 file.js 文件,代码如下所示:
1 | var fs = require("fs"); |
以上代码执行结果如下:
准备打开文件!
文件打开成功!
截取10字节内的文件内容,超出部分将被去除。
文件截取成功。
读取相同的文件
我是通
文件关闭成功!
3.8 删除文件
语法
fs.unlink(path, callback)
参数
参数使用说明如下:
path - 文件路径。
callback - 回调函数,没有参数。
实例
接下来我们修改 file.js 文件,代码如下所示:
1 | var fs = require("fs"); |
以上代码执行结果如下:
准备删除文件!
文件删除成功!
再去查看 input.txt 文件,发现已经不存在了。
3.9 创建目录
语法
fs.mkdir(path[, options], callback)
参数
参数使用说明如下:
path - 文件路径。
options 参数可以是:
recursive - 是否以递归的方式创建目录,默认为 false。
mode - 设置目录权限,默认为 0777。
callback - 回调函数,没有参数。
实例
接下来我们修改 file.js 文件,代码如下所示:
1 | var fs = require("fs"); |
以上代码执行结果如下:
创建目录 test
目录创建成功。
可以添加 recursive: true 参数,不管创建的目录 tmp 和 tmp/a 是否存在:
1 | fs.mkdir('tmp/a/apple', { recursive: true }, (err) => { |
3.10 读取目录
语法
fs.readdir(path, callback)
参数
参数使用说明如下:
path - 文件路径。
callback - 回调函数,回调函数带有两个参数err, files,err 为错误信息,files 为 目录下的文件数组列表。
实例
接下来我们修改 file.js 文件,代码如下所示:
1 | var fs = require("fs"); |
以上代码执行结果如下:
查看 tmp 目录
a
3.11 删除目录
语法
fs.rmdir(path, callback)
参数
参数使用说明如下:
path - 文件路径。
callback - 回调函数,没有参数。
实例
接下来我们修改 file.js 文件,代码如下所示:
1 | var fs = require("fs"); |
以上代码执行结果如下:
准备删除目录 tmp/a/apple
读取 tmp/a/apple 目录
[Error: ENOENT: no such file or directory, scandir 'E:\workspace\workspace(nodejs)\day03\tmp\a\apple'] {
errno: -4058,
code: 'ENOENT',
syscall: 'scandir',
path: 'E:\workspace\workspace(nodejs)\day03\tmp\a\apple'
}
3.12 文件模块方法参考手册
以下为 Node.js 文件模块相同的方法列表:
方法 | 描述 |
---|---|
fs.rename(oldPath, newPath, callback) | 异步 rename().回调函数没有参数,但可能抛出异常。 |
fs.ftruncate(fd, len, callback) | 异步 ftruncate().回调函数没有参数,但可能抛出异常。 |
fs.ftruncateSync(fd, len) | 同步 ftruncate() |
fs.truncate(path, len, callback) | 异步 truncate().回调函数没有参数,但可能抛出异常。 |
fs.truncateSync(path, len) | 同步 truncate() |
fs.chown(path, uid, gid, callback) | 异步 chown().回调函数没有参数,但可能抛出异常。 |
fs.chownSync(path, uid, gid) | 同步 chown() |
fs.fchown(fd, uid, gid, callback) | 异步 fchown().回调函数没有参数,但可能抛出异常。 |
fs.fchownSync(fd, uid, gid) | 同步 fchown() |
fs.lchown(path, uid, gid, callback) | 异步 lchown().回调函数没有参数,但可能抛出异常。 |
fs.lchownSync(path, uid, gid) | 同步 lchown() |
fs.chmod(path, mode, callback) | 异步 chmod().回调函数没有参数,但可能抛出异常。 |
fs.chmodSync(path, mode) | 同步 chmod(). |
fs.fchmod(fd, mode, callback) | 异步 fchmod().回调函数没有参数,但可能抛出异常。 |
fs.fchmodSync(fd, mode) | 同步 fchmod(). |
fs.lchmod(path, mode, callback) | 异步 lchmod().回调函数没有参数,但可能抛出异常。Only available on Mac OS X. |
fs.lchmodSync(path, mode) | 同步 lchmod(). |
fs.stat(path, callback) | 异步 stat(). 回调函数有两个参数 err, stats,stats 是 fs.Stats 对象。 |
fs.lstat(path, callback) | 异步 lstat(). 回调函数有两个参数 err, stats,stats 是 fs.Stats 对象。 |
fs.fstat(fd, callback) | 异步 fstat(). 回调函数有两个参数 err, stats,stats 是 fs.Stats 对象。 |
fs.statSync(path) | 同步 stat(). 返回 fs.Stats 的实例。 |
fs.lstatSync(path) | 同步 lstat(). 返回 fs.Stats 的实例。 |
fs.fstatSync(fd) | 同步 fstat(). 返回 fs.Stats 的实例。 |
fs.link(srcpath, dstpath, callback) | 异步 link().回调函数没有参数,但可能抛出异常。 |
fs.linkSync(srcpath, dstpath) | 同步 link(). |
fs.symlink(srcpath, dstpath[, type], callback) | 异步 symlink().回调函数没有参数,但可能抛出异常。 type 参数可以设置为 'dir', 'file', 或 'junction' (默认为 'file') 。 |
fs.symlinkSync(srcpath, dstpath[, type]) | 同步 symlink(). |
fs.readlink(path, callback) | 异步 readlink(). 回调函数有两个参数 err, linkString。 |
fs.realpath(path[, cache], callback) | 异步 realpath(). 回调函数有两个参数 err, resolvedPath。 |
fs.realpathSync(path[, cache]) | 同步 realpath()。返回绝对路径。 |
fs.unlink(path, callback) | 异步 unlink().回调函数没有参数,但可能抛出异常。 |
fs.unlinkSync(path) | 同步 unlink(). |
fs.rmdir(path, callback) | 异步 rmdir().回调函数没有参数,但可能抛出异常。 |
fs.rmdirSync(path) | 同步 rmdir(). |
fs.mkdir(path[, mode], callback) | S异步 mkdir(2).回调函数没有参数,但可能抛出异常。 访问权限默认为 0777。 |
fs.mkdirSync(path[, mode]) | 同步 mkdir(). |
fs.readdir(path, callback) | 异步 readdir(3). 读取目录的内容。 |
fs.readdirSync(path) | 同步 readdir().返回文件数组列表。 |
fs.close(fd, callback) | 异步 close().回调函数没有参数,但可能抛出异常。 |
fs.closeSync(fd) | 同步 close(). |
fs.open(path, flags[, mode], callback) | 异步打开文件。 |
fs.openSync(path, flags[, mode]) | 同步 version of fs.open(). |
fs.utimes(path, atime, mtime, callback) | |
fs.utimesSync(path, atime, mtime) | 修改文件时间戳,文件通过指定的文件路径。 |
fs.futimes(fd, atime, mtime, callback) | |
fs.futimesSync(fd, atime, mtime) | 修改文件时间戳,通过文件描述符指定。 |
fs.fsync(fd, callback) | 异步 fsync.回调函数没有参数,但可能抛出异常。 |
fs.fsyncSync(fd) | 同步 fsync. |
fs.write(fd, buffer, offset, length[, position], callback) | 将缓冲区内容写入到通过文件描述符指定的文件。 |
fs.write(fd, data[, position[, encoding]], callback) | 通过文件描述符 fd 写入文件内容。 |
fs.writeSync(fd, buffer, offset, length[, position]) | 同步版的 fs.write()。 |
fs.writeSync(fd, data[, position[, encoding]]) | 同步版的 fs.write(). |
fs.read(fd, buffer, offset, length, position, callback) | 通过文件描述符 fd 读取文件内容。 |
fs.readSync(fd, buffer, offset, length, position) | 同步版的 fs.read. |
fs.readFile(filename[, options], callback) | 异步读取文件内容。 |
fs.readFileSync(filename[, options]) | |
fs.writeFile(filename, data[, options], callback) | 异步写入文件内容。 |
fs.writeFileSync(filename, data[, options]) | 同步版的 fs.writeFile。 |
fs.appendFile(filename, data[, options], callback) | 异步追加文件内容。 |
fs.appendFileSync(filename, data[, options]) | The 同步 version of fs.appendFile. |
fs.watchFile(filename[, options], listener) | 查看文件的修改。 |
fs.unwatchFile(filename[, listener]) | 停止查看 filename 的修改。 |
fs.watch(filename[, options][, listener]) | 查看 filename 的修改,filename 可以是文件或目录。返回 fs.FSWatcher 对象。 |
fs.exists(path, callback) | 检测给定的路径是否存在。 |
fs.existsSync(path) | 同步版的 fs.exists. |
fs.access(path[, mode], callback) | 测试指定路径用户权限。 |
fs.accessSync(path[, mode]) | 同步版的 fs.access。 |
fs.createReadStream(path[, options]) | 返回ReadStream 对象。 |
fs.createWriteStream(path[, options]) | 返回 WriteStream 对象。 |
fs.symlink(srcpath, dstpath[, type], callback) | 异步 symlink().回调函数没有参数,但可能抛出异常。 |
四、GET/POST请求
在很多场景中,我们的服务器都需要跟用户的浏览器打交道,如表单提交。
表单提交到服务器一般都使用 GET/POST 请求。
本章节我们将为大家介绍 Node.js GET/POST请求。
4.1 获取GET请求内容
由于GET请求直接被嵌入在路径中,URL是完整的请求路径,包括了?后面的部分,因此你可以手动解析后面的内容作为GET请求的参数。
node.js 中 url 模块中的 parse 函数提供了这个功能。
实例
创建 httpRequest.js 文件, 代码如下:
1 | var http = require('http'); |
在浏览器中访问 http://localhost:3000/user?name=node学习&url=www.wno704.com 然后查看返回结果:
获取 URL 的参数
我们可以使用 url.parse 方法来解析 URL 中的参数,代码如下:
1 | var http = require('http'); |
在浏览器中访问 http://localhost:3000/user?name=node学习&url=www.wno704.com 然后查看返回结果:
4.2 获取 POST 请求内容
POST 请求的内容全部的都在请求体中,http.ServerRequest 并没有一个属性内容为请求体,原因是等待请求体传输可能是一件耗时的工作。
比如上传文件,而很多时候我们可能并不需要理会请求体的内容,恶意的POST请求会大大消耗服务器的资源,所以 node.js 默认是不会解析请求体的,当你需要的时候,需要手动来做。
1 | var http = require('http'); |
以下实例表单通过 POST 提交并输出数据:
1 | var http = require('http'); |
改造版代码
我们新建 from.html,内容为:
1 | <html> |
修改httpRequest.js
1 | var http = require('http'); |
测试效果和上面一样
五、Web 模块
5.1 什么是 Web 服务器?
Web服务器一般指网站服务器,是指驻留于因特网上某种类型计算机的程序,Web服务器的基本功能就是提供Web信息浏览服务。它只需支持HTTP协议、HTML文档格式及URL,与客户端的网络浏览器配合。
大多数 web 服务器都支持服务端的脚本语言(php、python、ruby)等,并通过脚本语言从数据库获取数据,将结果返回给客户端浏览器。
目前最主流的三个Web服务器是Apache、Nginx、IIS。
5.2 Web 应用架构
Client - 客户端,一般指浏览器,浏览器可以通过 HTTP 协议向服务器请求数据。
Server - 服务端,一般指 Web 服务器,可以接收客户端请求,并向客户端发送响应数据。
Business - 业务层, 通过 Web 服务器处理应用程序,如与数据库交互,逻辑运算,调用外部程序等。
Data - 数据层,一般由数据库组成。
5.3 使用 Node 创建 Web 服务器
Node.js 提供了 http 模块,http 模块主要用于搭建 HTTP 服务端和客户端,使用 HTTP 服务器或客户端功能必须调用 http 模块,代码如下:
1 | var http = require('http'); |
以下是演示一个最基本的 HTTP 服务器架构(使用 8080 端口),创建 server.js 文件,代码如下所示:
1 |
|
接下来我们在该目录下创建一个 index.html 文件,代码如下:
1 | <!DOCTYPE html> |
执行 web.js 文件:
Server running at http://127.0.0.1:8080/
接着我们在浏览器中打开地址: http://127.0.0.1:8080/index.html ,显示如下图所示:
web.js 的控制台输出信息如下:
Server running at http://127.0.0.1:8080/
Request for /index.html received.
Request for /favicon.ico received.
[Error: ENOENT: no such file or directory, open 'E:\workspace\workspace(nodejs)\day03\favicon.ico'] {
errno: -4058,
code: 'ENOENT',
syscall: 'open',
path: 'E:\workspace\workspace(nodejs)\day03\favicon.ico'
}
5.4 使用 Node 创建 Web 客户端
Node 创建 Web 客户端需要引入 http 模块,创建 client.js 文件,代码如下所示:
1 | var options = { |
新开一个终端,执行 client.js 文件,输出结果如下:
我的第一个标题
我的第一个段落。
web.js 的控制台输出信息如下:
Request for /index.html received.
六、工具模块
在 Node.js 模块库中有很多好用的模块。接下来我们为大家介绍几种常用模块的使用:
模块名 | 描述 |
---|---|
OS 模块 | 提供基本的系统操作函数。 |
Path 模块 | 提供了处理和转换文件路径的工具。 |
Net 模块 | 用于底层的网络通信。提供了服务端和客户端的的操作。 |
DNS 模块 | 用于解析域名。 |
Domain 模块 | 简化异步代码的异常处理,可以捕捉处理try catch无法捕捉的。 |
6.1 OS 模块
Node.js os 模块提供了一些基本的系统操作函数。我们可以通过以下方式引入该模块:
var os = require("os");
方法
方法 | 描述 |
---|---|
os.tmpdir() | 返回操作系统的默认临时文件夹。 |
os.endianness() | 返回 CPU 的字节序,可能的是 "BE" 或 "LE"。 |
os.hostname() | 返回操作系统的主机名。 |
os.type() | 返回操作系统名 |
os.platform() | 返回编译时的操作系统名 |
os.arch() | 返回操作系统 CPU 架构,可能的值有 "x64"、"arm" 和 "ia32"。 |
os.release() | 返回操作系统的发行版本。 |
os.uptime() | 返回操作系统运行的时间,以秒为单位。 |
os.loadavg() | 返回一个包含 1、5、15 分钟平均负载的数组。 |
os.totalmem() | 返回系统内存总量,单位为字节。 |
os.freemem() | 返回操作系统空闲内存量,单位是字节。 |
os.cpus() | 返回一个对象数组,包含所安装的每个 CPU/内核的信息:型号、速度(单位 MHz)、时间(一个包含 user、nice、sys、idle 和 irq 所使用 CPU/内核毫秒数的对象)。 |
os.networkInterfaces() | 获得网络接口列表。 |
属性
属性 | 描述 |
---|---|
os.EOL | 定义了操作系统的行尾符的常量。 |
实例
创建 os.js 文件,代码如下所示:
1 | var os = require("os"); |
代码执行结果如下:
endianness : LE
type : Windows_NT
platform : win32
total memory : 17047015424 bytes.
free memory : 9508794368 bytes.
6.2 Path 模块
Node.js path 模块提供了一些用于处理文件路径的小工具,我们可以通过以下方式引入该模块:
var path = require("path")
方法
方法 | 描述 |
---|---|
path.normalize(p) | 规范化路径,注意'..' 和 '.'。 |
path.join([path1][, path2][, ...]) | 用于连接路径。该方法的主要用途在于,会正确使用当前系统的路径分隔符,Unix系统是"/",Windows系统是""。 |
path.resolve([from ...], to) | 将 to 参数解析为绝对路径,给定的路径的序列是从右往左被处理的,后面每个 path 被依次解析,直到构造完成一个绝对路径。 例如,给定的路径片段的序列为:/foo、/bar、baz,则调用 path.resolve('/foo', '/bar', 'baz') 会返回 /bar/baz。 |
path.isAbsolute(path) | 判断参数 path 是否是绝对路径。 |
path.relative(from, to) | 用于将绝对路径转为相对路径,返回从 from 到 to 的相对路径(基于当前工作目录)。在 Linux 上:path.relative('/data/orandea/test/aaa', '/data/orandea/impl/bbb'); 在 Windows 上:path.relative('C:\orandea\test\aaa', 'C:\orandea\impl\bbb'); |
path.dirname(p) | 返回路径中代表文件夹的部分,同 Unix 的dirname 命令类似。 |
path.basename(p[, ext]) | 返回路径中的最后一部分。同 Unix 命令 bashname 类似。 |
path.extname(p) | 返回路径中文件的后缀名,即路径中最后一个'.'之后的部分。如果一个路径中并不包含'.'或该路径只包含一个'.' 且这个'.'为路径的第一个字符,则此命令返回空字符串。 |
path.parse(pathString) | 返回路径字符串的对象。 |
path.format(pathObject) | 从对象中返回路径字符串,和 path.parse 相反。 |
属性
属性 | 描述 |
---|---|
path.sep | 平台的文件路径分隔符,'\' 或 '/'。 |
path.delimiter | 平台的分隔符, ; or ':'. |
path.posix | 提供上述 path 的方法,不过总是以 posix 兼容的方式交互。 |
path.win32 | 提供上述 path 的方法,不过总是以 win32 兼容的方式交互。 |
实例
创建 path.js 文件,代码如下所示:
1 | var path = require("path"); |
代码执行结果如下:
normalization : test\test1\2slashes\1slash
joint path : test\test1\2slashes\1slash
resolve : E:\workspace\workspace(nodejs)\day03\main.js
ext name : .js
6.3 Net 模块
Node.js Net 模块提供了一些用于底层的网络通信的小工具,包含了创建服务器/客户端的方法,我们可以通过以下方式引入该模块:
var net = require("net")
方法
方法 | 描述 |
---|---|
net.createServer([options][, connectionListener]) | 创建一个 TCP 服务器。参数 connectionListener 自动给 'connection' 事件创建监听器。 |
net.connect(options[, connectionListener]) | 返回一个新的 'net.Socket',并连接到指定的地址和端口。当 socket 建立的时候,将会触发 'connect' 事件。 |
net.createConnection(options[, connectionListener]) | 创建一个到端口 port 和 主机 host的 TCP 连接。 host 默认为 'localhost'。 |
net.connect(port[, host][, connectListener]) | 创建一个端口为 port 和主机为 host的 TCP 连接 。host 默认为 'localhost'。参数 connectListener 将会作为监听器添加到 'connect' 事件。返回 'net.Socket'。 |
net.createConnection(port[, host][, connectListener]) | 创建一个端口为 port 和主机为 host的 TCP 连接 。host 默认为 'localhost'。参数 connectListener 将会作为监听器添加到 'connect' 事件。返回 'net.Socket'。 |
net.connect(path[, connectListener]) | 创建连接到 path 的 unix socket 。参数 connectListener 将会作为监听器添加到 'connect' 事件上。返回 'net.Socket'。 |
net.createConnection(path[, connectListener]) | 创建连接到 path 的 unix socket 。参数 connectListener 将会作为监听器添加到 'connect' 事件。返回 'net.Socket'。 |
net.isIP(input) | 检测输入的是否为 IP 地址。 IPV4 返回 4, IPV6 返回 6,其他情况返回 0。 |
net.isIPv4(input) | 如果输入的地址为 IPV4, 返回 true,否则返回 false。 |
net.isIPv6(input) | 如果输入的地址为 IPV6, 返回 true,否则返回 false。 |
net.Server
net.Server通常用于创建一个 TCP 或本地服务器。
方法
方法 | 描述 |
---|---|
server.listen(port[, host][, backlog][, callback]) | 监听指定端口 port 和 主机 host ac连接。 默认情况下 host 接受任何 IPv4 地址(INADDR_ANY)的直接连接。端口 port 为 0 时,则会分配一个随机端口。 |
server.listen(path[, callback]) | 通过指定 path 的连接,启动一个本地 socket 服务器。 |
server.listen(handle[, callback]) | 通过指定句柄连接。 |
server.listen(options[, callback]) | options 的属性:端口 port, 主机 host, 和 backlog, 以及可选参数 callback 函数, 他们在一起调用server.listen(port, [host], [backlog], [callback])。还有,参数 path 可以用来指定 UNIX socket。 |
server.close([callback]) | 服务器停止接收新的连接,保持现有连接。这是异步函数,当所有连接结束的时候服务器会关闭,并会触发 'close' 事件。 |
server.address() | 操作系统返回绑定的地址,协议族名和服务器端口。 |
server.unref() | 如果这是事件系统中唯一一个活动的服务器,调用 unref 将允许程序退出。 |
server.ref() | 与 unref 相反,如果这是唯一的服务器,在之前被 unref 了的服务器上调用 ref 将不会让程序退出(默认行为)。如果服务器已经被 ref,则再次调用 ref 并不会产生影响。 |
server.getConnections(callback) | 异步获取服务器当前活跃连接的数量。当 socket 发送给子进程后才有效;回调函数有 2 个参数 err 和 count。 |
net.Server 事件
事件 | 描述 |
---|---|
listening | 当服务器调用 server.listen 绑定后会触发。 |
connection | 当新连接创建后会被触发。socket 是 net.Socket实例。 |
close | 服务器关闭时会触发。注意,如果存在连接,这个事件不会被触发直到所有的连接关闭。 |
error | 发生错误时触发。'close' 事件将被下列事件直接调用。 |
net.Socket
net.Socket 对象是 TCP 或 UNIX Socket 的抽象。net.Socket 实例实现了一个双工流接口。 他们可以在用户创建客户端(使用 connect())时使用, 或者由 Node 创建它们,并通过 connection 服务器事件传递给用户。
事件
net.Socket 事件
事件 | 描述 |
---|---|
lookup | 在解析域名后,但在连接前,触发这个事件。对 UNIX sokcet 不适用。 |
connect | 成功建立 socket 连接时触发。 |
data | 当接收到数据时触发。 |
end | 当 socket 另一端发送 FIN 包时,触发该事件。 |
timeout | 当 socket 空闲超时时触发,仅是表明 socket 已经空闲。用户必须手动关闭连接。 |
drain | 当写缓存为空得时候触发。可用来控制上传。 |
error | 错误发生时触发。 |
close | 当 socket 完全关闭时触发。参数 had_error 是布尔值,它表示是否因为传输错误导致 socket 关闭。 |
属性
net.Socket 提供了很多有用的属性,便于控制 socket 交互:
属性 | 描述 |
---|---|
socket.bufferSize | 该属性显示了要写入缓冲区的字节数。 |
socket.remoteAddress | 远程的 IP 地址字符串,例如:'74.125.127.100' or '2001:4860:a005::68'。 |
socket.remoteFamily | 远程IP协议族字符串,比如 'IPv4' or 'IPv6'。 |
socket.remotePort | 远程端口,数字表示,例如:80 or 21。 |
socket.localAddress | 网络连接绑定的本地接口 远程客户端正在连接的本地 IP 地址,字符串表示。例如,如果你在监听'0.0.0.0'而客户端连接在'192.168.1.1',这个值就会是 '192.168.1.1'。 |
socket.localPort | 本地端口地址,数字表示。例如:80 or 21。 |
socket.bytesRead | 接收到得字节数。 |
socket.bytesWritten | 发送的字节数。 |
方法
方法 | 描述 |
---|---|
new net.Socket([options]) | 构造一个新的 socket 对象。 |
socket.connect(port[, host][, connectListener]) | 指定端口 port 和 主机 host,创建 socket 连接 。参数 host 默认为 localhost。通常情况不需要使用 net.createConnection 打开 socket。只有你实现了自己的 socket 时才会用到。 |
socket.connect(path[, connectListener]) | 打开指定路径的 unix socket。通常情况不需要使用 net.createConnection 打开 socket。只有你实现了自己的 socket 时才会用到。 |
socket.setEncoding([encoding]) | 设置编码 |
socket.write(data[, encoding][, callback]) | 在 socket 上发送数据。第二个参数指定了字符串的编码,默认是 UTF8 编码。 |
socket.end([data][, encoding]) | 半关闭 socket。例如,它发送一个 FIN 包。可能服务器仍在发送数据。 |
socket.destroy() | 确保没有 I/O 活动在这个套接字上。只有在错误发生情况下才需要。(处理错误等等)。 |
socket.pause() | 暂停读取数据。就是说,不会再触发 data 事件。对于控制上传非常有用。 |
socket.resume() | 调用 pause() 后想恢复读取数据。 |
socket.setTimeout(timeout[, callback]) | socket 闲置时间超过 timeout 毫秒后 ,将 socket 设置为超时。 |
socket.setNoDelay([noDelay]) | 禁用纳格(Nagle)算法。默认情况下 TCP 连接使用纳格算法,在发送前他们会缓冲数据。将 noDelay 设置为 true 将会在调用 socket.write() 时立即发送数据。noDelay 默认值为 true。 |
socket.setKeepAlive([enable][, initialDelay]) | 禁用/启用长连接功能,并在发送第一个在闲置 socket 上的长连接 probe 之前,可选地设定初始延时。默认为 false。 设定 initialDelay (毫秒),来设定收到的最后一个数据包和第一个长连接probe之间的延时。将 initialDelay 设为0,将会保留默认(或者之前)的值。默认值为0. |
socket.address() | 操作系统返回绑定的地址,协议族名和服务器端口。返回的对象有 3 个属性,比如{ port: 12346, family: 'IPv4', address: '127.0.0.1' }。 |
socket.unref() | 如果这是事件系统中唯一一个活动的服务器,调用 unref 将允许程序退出。如果服务器已被 unref,则再次调用 unref 并不会产生影响。 |
socket.ref() | 与 unref 相反,如果这是唯一的服务器,在之前被 unref 了的服务器上调用 ref 将不会让程序退出(默认行为)。如果服务器已经被 ref,则再次调用 ref 并不会产生影响。 |
实例
创建 netserver.js 文件,代码如下所示:
1 | var net = require('net'); |
执行以上服务端代码:
server is listening
新开一个窗口,创建 netclient.js 文件,代码如下所示:
1 | var net = require('net'); |
执行以上客户端的代码:
1 | 连接到服务器! |
6.4 DNS 模块
Node.js DNS 模块用于解析域名。引入 DNS 模块语法格式如下:
var dns = require("dns")
方法
方法 | 描述 |
---|---|
dns.lookup(hostname[, options], callback) | 将域名(比如 'runoob.com')解析为第一条找到的记录 A (IPV4)或 AAAA(IPV6)。参数 options可以是一个对象或整数。如果没有提供 options,IP v4 和 v6 地址都可以。如果 options 是整数,则必须是 4 或 6。 |
dns.lookupService(address, port, callback) | 使用 getnameinfo 解析传入的地址和端口为域名和服务。 |
dns.resolve(hostname[, rrtype], callback) | 将一个域名(如 'runoob.com')解析为一个 rrtype 指定记录类型的数组。 |
dns.resolve4(hostname, callback) | 和 dns.resolve() 类似, 仅能查询 IPv4 (A 记录)。 addresses IPv4 地址数组 (比如,['74.125.79.104', '74.125.79.105', '74.125.79.106'])。 |
dns.resolve6(hostname, callback) | 和 dns.resolve4() 类似, 仅能查询 IPv6( AAAA 查询) |
dns.resolveMx(hostname, callback) | 和 dns.resolve() 类似, 仅能查询邮件交换(MX 记录)。 |
dns.resolveTxt(hostname, callback) | 和 dns.resolve() 类似, 仅能进行文本查询 (TXT 记录)。 addresses 是 2-d 文本记录数组。(比如,[ ['v=spf1 ip4:0.0.0.0 ', '~all' ] ])。 每个子数组包含一条记录的 TXT 块。根据使用情况可以连接在一起,也可单独使用。 |
dns.resolveSrv(hostname, callback) | 和 dns.resolve() 类似, 仅能进行服务记录查询 (SRV 记录)。 addresses 是 hostname可用的 SRV 记录数组。 SRV 记录属性有优先级(priority),权重(weight), 端口(port), 和名字(name) (比如,[{'priority': 10, 'weight': 5, 'port': 21223, 'name': 'service.example.com'}, ...])。 |
dns.resolveSoa(hostname, callback) | 和 dns.resolve() 类似, 仅能查询权威记录(SOA 记录)。 |
dns.resolveNs(hostname, callback) | 和 dns.resolve() 类似, 仅能进行域名服务器记录查询(NS 记录)。 addresses 是域名服务器记录数组(hostname 可以使用) (比如, ['ns1.example.com', 'ns2.example.com'])。 |
dns.resolveCname(hostname, callback) | 和 dns.resolve() 类似, 仅能进行别名记录查询 (CNAME记录)。addresses 是对 hostname 可用的别名记录数组 (比如,, ['bar.example.com'])。 |
dns.reverse(ip, callback) | 反向解析 IP 地址,指向该 IP 地址的域名数组。 |
dns.getServers() | 返回一个用于当前解析的 IP 地址数组的字符串。 |
dns.setServers(servers) | 指定一组 IP 地址作为解析服务器。 |
rrtypes
以下列出了 dns.resolve() 方法中有效的 rrtypes值:
'A' IPV4 地址, 默认
'AAAA' IPV6 地址
'MX' 邮件交换记录
'TXT' text 记录
'SRV' SRV 记录
'PTR' 用来反向 IP 查找
'NS' 域名服务器记录
'CNAME' 别名记录
'SOA' 授权记录的初始值
错误码
每次 DNS 查询都可能返回以下错误码:
dns.NODATA: 无数据响应。
dns.FORMERR: 查询格式错误。
dns.SERVFAIL: 常规失败。
dns.NOTFOUND: 没有找到域名。
dns.NOTIMP: 未实现请求的操作。
dns.REFUSED: 拒绝查询。
dns.BADQUERY: 查询格式错误。
dns.BADNAME: 域名格式错误。
dns.BADFAMILY: 地址协议不支持。
dns.BADRESP: 回复格式错误。
dns.CONNREFUSED: 无法连接到 DNS 服务器。
dns.TIMEOUT: 连接 DNS 服务器超时。
dns.EOF: 文件末端。
dns.FILE: 读文件错误。
dns.NOMEM: 内存溢出。
dns.DESTRUCTION: 通道被摧毁。
dns.BADSTR: 字符串格式错误。
dns.BADFLAGS: 非法标识符。
dns.NONAME: 所给主机不是数字。
dns.BADHINTS: 非法HINTS标识符。
dns.NOTINITIALIZED: c c-ares 库尚未初始化。
dns.LOADIPHLPAPI: 加载 iphlpapi.dll 出错。
dns.ADDRGETNETWORKPARAMS: 无法找到 GetNetworkParams 函数。
dns.CANCELLED: 取消 DNS 查询。
实例
创建 dns.js 文件,代码如下所示:
1 | var dns = require('dns'); |
执行以上代码,结果如下所示:
ip 地址: 13.250.177.223
反向解析 13.250.177.223: ["ec2-13-250-177-223.ap-southeast-1.compute.amazonaws.com"]
6.5 Domain 模块
Node.js Domain(域) 简化异步代码的异常处理,可以捕捉处理try catch无法捕捉的异常。引入 Domain 模块 语法格式如下:
var domain = require("domain")
domain模块,把处理多个不同的IO的操作作为一个组。注册事件和回调到domain,当发生一个错误事件或抛出一个错误时,domain对象会被通知,不会丢失上下文环境,也不导致程序错误立即退出,与process.on('uncaughtException')不同。
Domain 模块可分为隐式绑定和显式绑定:
隐式绑定: 把在domain上下文中定义的变量,自动绑定到domain对象
显式绑定: 把不是在domain上下文中定义的变量,以代码的方式绑定到domain对象
方法
方法 | 描述 |
---|---|
domain.run(function) | 在域的上下文运行提供的函数,隐式的绑定了所有的事件分发器,计时器和底层请求。 |
domain.add(emitter) | 显式的增加事件 |
domain.remove(emitter) | 删除事件。 |
domain.bind(callback) | 返回的函数是一个对于所提供的回调函数的包装函数。当调用这个返回的函数时,所有被抛出的错误都会被导向到这个域的 error 事件。 |
domain.intercept(callback) | 和 domain.bind(callback) 类似。除了捕捉被抛出的错误外,它还会拦截 Error 对象作为参数传递到这个函数。 |
domain.enter() | 进入一个异步调用的上下文,绑定到domain。 |
domain.exit() | 退出当前的domain,切换到不同的链的异步调用的上下文中。对应domain.enter()。 |
domain.dispose() | 释放一个domain对象,让node进程回收这部分资源。 |
domain.create() | 返回一个domain对象。 |
属性
属性 | 描述 |
---|---|
domain.members | 已加入domain对象的域定时器和事件发射器的数组。 |
实例
创建 domain.js 文件,代码如下所示:
1 | var EventEmitter = require("events").EventEmitter; |
执行以上代码,结果如下所示:
1 | 监听器处理此错误 (通过监听器来处理) |