Node.js 工具模塊
在 Node.js 模塊庫中有很多好用的模塊。接下來我們爲大家介紹幾種常用模塊的使用:
序號 | 模塊名 & 描述 |
---|---|
1 |
OS 模塊 提供基本的系統操作函數。 |
2 |
Path 模塊 提供了處理和轉換文件路的工具。 |
3 |
Net 模塊 用於底層的網絡通信。提供了服務端和客戶端的的操作。 |
4 |
DNS 模塊 用於解析域名。 |
5 |
Domain 模塊 簡化異步代碼的異常處理,可以捕捉處理try catch無法捕捉的。 |
Node.js OS 模塊
Node.js os 模塊提供了一些基本的系統操作函數。我們可以通過以下方式引入該模塊:
var os = require("os")
方法
序號 | 方法 & 描述 |
---|---|
1 |
os.tmpdir() 返回操作系統的默認臨時文件夾。 |
2 |
os.endianness() 返回 CPU 的字節序,可能的是 "BE" 或 "LE"。 |
3 |
os.hostname() 返回操作系統的主機名。 |
4 |
os.type() 返回操作系統名 |
5 |
os.platform() 返回操作系統名 |
6 |
os.arch() 返回操作系統 CPU 架構,可能的值有 "x64"、"arm" 和 "ia32"。 |
7 |
os.release() 返回操作系統的發行版本。 |
8 |
os.uptime() 返回操作系統運行的時間,以秒爲單位。 |
9 |
os.loadavg() 返回一個包含 1、5、15 分鐘平均負載的數組。 |
10 |
os.totalmem() 返回系統內存總量,單位爲字節。 |
11 |
os.freemem() 返回操作系統空閒內存量,單位是字節。 |
12 |
os.cpus() 返回一個對象數組,包含所安裝的每個 CPU/內核的信息:型號、速度(單位 MHz)、時間(一個包含 user、nice、sys、idle 和 irq 所使用 CPU/內核毫秒數的對象)。 |
13 |
os.networkInterfaces() 獲得網絡接口列表。 |
屬性
序號 | 屬性 & 描述 |
---|---|
1 |
os.EOL 定義了操作系統的行尾符的常量。 |
實例
創建 main.js 文件,代碼如下所示:
var os = require("os"); // CPU 的字節序 console.log('endianness : ' + os.endianness()); // 操作系統名 console.log('type : ' + os.type()); // 操作系統名 console.log('platform : ' + os.platform()); // 系統內存總量 console.log('total memory : ' + os.totalmem() + " bytes."); // 操作系統空閒內存量 console.log('free memory : ' + os.freemem() + " bytes.");
代碼執行結果如下:
$ node main.js endianness : LE type : Linux platform : linux total memory : 25103400960 bytes. free memory : 20676710400 bytes.
Node.js Path 模塊
Node.js path 模塊提供了一些用於處理文件路徑的小工具,我們可以通過以下方式引入該模塊:
var path = require("path")
方法
序號 | 方法 & 描述 |
---|---|
1 |
path.normalize(p) 規範化路徑,注意'..' 和 '.'。 |
2 |
path.join([path1][, path2][, ...]) 用於連接路徑。該方法的主要用途在於,會正確使用當前系統的路徑分隔符,Unix系統是"/",Windows系統是"\"。 |
3 |
path.resolve([from ...], to) 將 to 參數解析爲絕對路徑。 |
4 |
path.isAbsolute(path) 判斷參數 path 是否是絕對路徑。 |
5 |
path.relative(from, to) 用於將相對路徑轉爲絕對路徑。 |
6 |
path.dirname(p) 返回路徑中代表文件夾的部分,同 Unix 的dirname 命令類似。 |
7 |
path.basename(p[, ext]) 返回路徑中的最後一部分。同 Unix 命令 bashname 類似。 |
8 |
path.extname(p) 返回路徑中文件的後綴名,即路徑中最後一個'.'之後的部分。如果一個路徑中並不包含'.'或該路徑只包含一個'.' 且這個'.'爲路徑的第一個字符,則此命令返回空字符串。 |
9 |
path.parse(pathString) 返回路徑字符串的對象。 |
10 |
path.format(pathObject) 從對象中返回路徑字符串,和 path.parse 相反。 |
屬性
序號 | 屬性 & 描述 |
---|---|
1 |
path.sep 平臺的文件路徑分隔符,'\\' 或 '/'。 |
2 |
path.delimiter 平臺的分隔符, ; or ':'. |
3 |
path.posix 提供上述 path 的方法,不過總是以 posix 兼容的方式交互。 |
4 |
path.win32 提供上述 path 的方法,不過總是以 win32 兼容的方式交互。 |
實例
創建 main.js 文件,代碼如下所示:
var path = require("path"); // 格式化路徑 console.log('normalization : ' + path.normalize('/test/test1//2slashes/1slash/tab/..')); // 連接路徑 console.log('joint path : ' + path.join('/test', 'test1', '2slashes/1slash', 'tab', '..')); // 轉換爲絕對路徑 console.log('resolve : ' + path.resolve('main.js')); // 路徑中文件的後綴名 console.log('ext name : ' + path.extname('main.js'));
代碼執行結果如下:
$ node main.js normalization : /test/test1/2slashes/1slash joint path : /test/test1/2slashes/1slash resolve : /web/com/1427176256_27423/main.js ext name : .js
Node.js Net 模塊
Node.js Net 模塊提供了一些用於底層的網絡通信的小工具,包含了創建服務器/客戶端的方法,我們可以通過以下方式引入該模塊:
var net = require("net")
方法
序號 | 方法 & 描述 |
---|---|
1 |
net.createServer([options][, connectionListener]) 創建一個 TCP 服務器。參數 connectionListener 自動給 'connection' 事件創建監聽器。 |
2 |
net.connect(options[, connectionListener]) 返回一個新的 'net.Socket',並連接到指定的地址和端口。 當 socket 建立的時候,將會觸發 'connect' 事件。 |
3 |
net.createConnection(options[, connectionListener]) 創建一個到端口 port 和 主機 host的 TCP 連接。 host 默認爲 'localhost'。 |
4 |
net.connect(port[, host][, connectListener]) 創建一個端口爲 port 和主機爲 host的 TCP 連接 。host 默認爲 'localhost'。參數 connectListener 將會作爲監聽器添加到 'connect' 事件。返回 'net.Socket'。 |
5 |
net.createConnection(port[, host][, connectListener]) 創建一個端口爲 port 和主機爲 host的 TCP 連接 。host 默認爲 'localhost'。參數 connectListener 將會作爲監聽器添加到 'connect' 事件。返回 'net.Socket'。 |
6 |
net.connect(path[, connectListener]) 創建連接到 path 的 unix socket 。參數 connectListener 將會作爲監聽器添加到 'connect' 事件上。返回 'net.Socket'。 |
7 |
net.createConnection(path[, connectListener]) 創建連接到 path 的 unix socket 。參數 connectListener 將會作爲監聽器添加到 'connect' 事件。返回 'net.Socket'。 |
8 |
net.isIP(input) 檢測輸入的是否爲 IP 地址。 IPV4 返回 4, IPV6 返回 6,其他情況返回 0。 |
9 |
net.isIPv4(input) 如果輸入的地址爲 IPV4, 返回 true,否則返回 false。 |
10 |
net.isIPv6(input) 如果輸入的地址爲 IPV6, 返回 true,否則返回 false。 |
net.Server
net.Server通常用於創建一個 TCP 或本地服務器。
序號 | 方法 & 描述 |
---|---|
1 |
server.listen(port[, host][, backlog][, callback]) 監聽指定端口 port 和 主機 host ac連接。 默認情況下 host 接受任何 IPv4 地址(INADDR_ANY)的直接連接。端口 port 爲 0 時,則會分配一個隨機端口。 |
2 |
server.listen(path[, callback]) 通過指定 path 的連接,啓動一個本地 socket 服務器。 |
3 |
server.listen(handle[, callback]) 通過指定句柄連接。 |
4 |
server.listen(options[, callback]) options 的屬性:端口 port, 主機 host, 和 backlog, 以及可選參數 callback 函數, 他們在一起調用server.listen(port, [host], [backlog], [callback])。還有,參數 path 可以用來指定 UNIX socket。 |
5 |
server.close([callback]) 服務器停止接收新的連接,保持現有連接。這是異步函數,當所有連接結束的時候服務器會關閉,並會觸發 'close' 事件。 |
6 |
server.address() 操作系統返回綁定的地址,協議族名和服務器端口。 |
7 |
server.unref() 如果這是事件系統中唯一一個活動的服務器,調用 unref 將允許程序退出。 |
8 |
server.ref() 與 unref 相反,如果這是唯一的服務器,在之前被 unref 了的服務器上調用 ref 將不會讓程序退出(默認行爲)。如果服務器已經被 ref,則再次調用 ref 並不會產生影響。 |
9 |
server.getConnections(callback) 異步獲取服務器當前活躍連接的數量。當 socket 發送給子進程後纔有效;回調函數有 2 個參數 err 和 count。 |
事件
序號 | 事件 & 描述 |
---|---|
1 |
listening 當服務器調用 server.listen 綁定後會觸發。 |
2 |
connection 當新連接創建後會被觸發。socket 是 net.Socket實例。 |
3 |
close 服務器關閉時會觸發。注意,如果存在連接,這個事件不會被觸發直到所有的連接關閉。 |
4 |
error 發生錯誤時觸發。'close' 事件將被下列事件直接調用。 |
net.Socket
net.Socket 對象是 TCP 或 UNIX Socket 的抽象。net.Socket 實例實現了一個雙工流接口。 他們可以在用戶創建客戶端(使用 connect())時使用, 或者由 Node 創建它們,並通過 connection 服務器事件傳遞給用戶。
事件
net.Socket 事件有:
序號 | 事件 & 描述 |
---|---|
1 |
lookup 在解析域名後,但在連接前,觸發這個事件。對 UNIX sokcet 不適用。 |
2 |
connect 成功建立 socket 連接時觸發。 |
3 |
data 當接收到數據時觸發。 |
4 |
end 當 socket 另一端發送 FIN 包時,觸發該事件。 |
5 |
timeout 當 socket 空閒超時時觸發,僅是表明 socket 已經空閒。用戶必須手動關閉連接。 |
6 |
drain 當寫緩存爲空得時候觸發。可用來控制上傳。 |
7 |
error 錯誤發生時觸發。 |
8 |
close 當 socket 完全關閉時觸發。參數 had_error 是布爾值,它表示是否因爲傳輸錯誤導致 socket 關閉。 |
屬性
net.Socket 提供了很多有用的屬性,便於控制 socket 交互:
序號 | 屬性 & 描述 |
---|---|
1 |
socket.bufferSize 該屬性顯示了要寫入緩衝區的字節數。 |
2 |
socket.remoteAddress 遠程的 IP 地址字符串,例如:'74.125.127.100' or '2001:4860:a005::68'。 |
3 |
socket.remoteFamily 遠程IP協議族字符串,比如 'IPv4' or 'IPv6'。 |
4 |
socket.remotePort 遠程端口,數字表示,例如:80 or 21。 |
5 |
socket.localAddress 網絡連接綁定的本地接口 遠程客戶端正在連接的本地 IP 地址,字符串表示。例如,如果你在監聽'0.0.0.0'而客戶端連接在'192.168.1.1',這個值就會是 '192.168.1.1'。 |
6 |
socket.localPort 本地端口地址,數字表示。例如:80 or 21。 |
7 |
socket.bytesRead 接收到得字節數。 |
8 |
socket.bytesWritten 發送的字節數。 |
方法
序號 | 方法 & 描述 |
---|---|
1 |
new net.Socket([options]) 構造一個新的 socket 對象。 |
2 |
socket.connect(port[, host][, connectListener]) 指定端口 port 和 主機 host,創建 socket 連接 。參數 host 默認爲 localhost。通常情況不需要使用 net.createConnection 打開 socket。只有你實現了自己的 socket 時纔會用到。 |
3 |
socket.connect(path[, connectListener]) 打開指定路徑的 unix socket。通常情況不需要使用 net.createConnection 打開 socket。只有你實現了自己的 socket 時纔會用到。 |
4 |
socket.setEncoding([encoding]) 設置編碼 |
5 |
socket.write(data[, encoding][, callback]) 在 socket 上發送數據。第二個參數指定了字符串的編碼,默認是 UTF8 編碼。 |
6 |
socket.end([data][, encoding]) 半關閉 socket。例如,它發送一個 FIN 包。可能服務器仍在發送數據。 |
7 |
socket.destroy() 確保沒有 I/O 活動在這個套接字上。只有在錯誤發生情況下才需要。(處理錯誤等等)。 |
8 |
socket.pause() 暫停讀取數據。就是說,不會再觸發 data 事件。對於控制上傳非常有用。 |
9 |
socket.resume() 調用 pause() 後想恢復讀取數據。 |
10 |
socket.setTimeout(timeout[, callback]) socket 閒置時間超過 timeout 毫秒後 ,將 socket 設置爲超時。 |
11 |
socket.setNoDelay([noDelay]) 禁用納格(Nagle)算法。默認情況下 TCP 連接使用納格算法,在發送前他們會緩衝數據。將 noDelay 設置爲 true 將會在調用 socket.write() 時立即發送數據。noDelay 默認值爲 true。 |
12 |
socket.setKeepAlive([enable][, initialDelay]) 禁用/啓用長連接功能,並在發送第一個在閒置 socket 上的長連接 probe 之前,可選地設定初始延時。默認爲 false。 設定 initialDelay (毫秒),來設定收到的最後一個數據包和第一個長連接probe之間的延時。將 initialDelay 設爲0,將會保留默認(或者之前)的值。默認值爲0. |
13 |
socket.address() 操作系統返回綁定的地址,協議族名和服務器端口。返回的對象有 3 個屬性,比如{ port: 12346, family: 'IPv4', address: '127.0.0.1' }。 |
14 |
socket.unref() 如果這是事件系統中唯一一個活動的服務器,調用 unref 將允許程序退出。如果服務器已被 unref,則再次調用 unref 並不會產生影響。 |
15 |
socket.ref() 與 unref 相反,如果這是唯一的服務器,在之前被 unref 了的服務器上調用 ref 將不會讓程序退出(默認行爲)。如果服務器已經被 ref,則再次調用 ref 並不會產生影響。 |
實例
創建 server.js 文件,代碼如下所示:
var net = require('net'); var server = net.createServer(function(connection) { console.log('client connected'); connection.on('end', function() { console.log('客戶端關閉連接'); }); connection.write('Hello World!\r\n'); connection.pipe(connection); }); server.listen(8080, function() { console.log('server is listening'); });
執行以上服務端代碼:
$ node server.js server is listening # 服務已創建並監聽 8080 端口
新開一個窗口,創建 client.js 文件,代碼如下所示:
var net = require('net'); var client = net.connect({port: 8080}, function() { console.log('連接到服務器!'); }); client.on('data', function(data) { console.log(data.toString()); client.end(); }); client.on('end', function() { console.log('斷開與服務器的連接'); });
執行以上客戶端的代碼:
連接到服務器! Hello World! 斷開與服務器的連接
Gif 實例演示
Node.js DNS 模塊
Node.js DNS 模塊用於解析域名。引入 DNS 模塊語法格式如下:
var dns = require("dns")
方法
序號 | 方法 & 描述 |
---|---|
1 |
dns.lookup(hostname[, options], callback) 將域名(比如 'runoob.com')解析爲第一條找到的記錄 A (IPV4)或 AAAA(IPV6)。參數 options可以是一個對象或整數。如果沒有提供 options,IP v4 和 v6 地址都可以。如果 options 是整數,則必須是 4 或 6。 |
2 |
dns.lookupService(address, port, callback) 使用 getnameinfo 解析傳入的地址和端口爲域名和服務。 |
3 |
dns.resolve(hostname[, rrtype], callback) 將一個域名(如 'runoob.com')解析爲一個 rrtype 指定記錄類型的數組。 |
4 |
dns.resolve4(hostname, callback) 和 dns.resolve() 類似, 僅能查詢 IPv4 (A 記錄)。 addresses IPv4 地址數組 (比如,['74.125.79.104', '74.125.79.105', '74.125.79.106'])。 |
5 |
dns.resolve6(hostname, callback) 和 dns.resolve4() 類似, 僅能查詢 IPv6( AAAA 查詢) |
6 |
dns.resolveMx(hostname, callback) 和 dns.resolve() 類似, 僅能查詢郵件交換(MX 記錄)。 |
7 |
dns.resolveTxt(hostname, callback) 和 dns.resolve() 類似, 僅能進行文本查詢 (TXT 記錄)。 addresses 是 2-d 文本記錄數組。(比如,[ ['v=spf1 ip4:0.0.0.0 ', '~all' ] ])。 每個子數組包含一條記錄的 TXT 塊。根據使用情況可以連接在一起,也可單獨使用。 |
8 |
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'}, ...])。 |
9 |
dns.resolveSoa(hostname, callback) 和 dns.resolve() 類似, 僅能查詢權威記錄(SOA 記錄)。 |
10 |
dns.resolveNs(hostname, callback) 和 dns.resolve() 類似, 僅能進行域名服務器記錄查詢(NS 記錄)。 addresses 是域名服務器記錄數組(hostname 可以使用) (比如, ['ns1.example.com', 'ns2.example.com'])。 |
11 |
dns.resolveCname(hostname, callback) 和 dns.resolve() 類似, 僅能進行別名記錄查詢 (CNAME記錄)。addresses 是對 hostname 可用的別名記錄數組 (比如,, ['bar.example.com'])。 |
12 |
dns.reverse(ip, callback) 反向解析 IP 地址,指向該 IP 地址的域名數組。 |
13 |
dns.getServers() 返回一個用於當前解析的 IP 地址數組的字符串。 |
14 |
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 查詢。
實例
創建 main.js 文件,代碼如下所示:
var dns = require('dns'); dns.lookup('www.github.com', function onLookup(err, address, family) { console.log('ip 地址:', address); dns.reverse(address, function (err, hostnames) { if (err) { console.log(err.stack); } console.log('反向解析 ' + address + ': ' + JSON.stringify(hostnames)); }); });
執行以上代碼,結果如下所示:
address: 192.30.252.130 reverse for 192.30.252.130: ["github.com"]
Node.js Domain 模塊
Node.js Domain(域) 簡化異步代碼的異常處理,可以捕捉處理try catch無法捕捉的異常。引入 Domain 模塊 語法格式如下:
var domain = require("domain")
domain模塊,把處理多個不同的IO的操作作爲一個組。註冊事件和回調到domain,當發生一個錯誤事件或拋出一個錯誤時,domain對象會被通知,不會丟失上下文環境,也不導致程序錯誤立即推出,與process.on('uncaughtException')不同。
Domain 模塊可分爲隱式綁定和顯式綁定:
- 隱式綁定: 把在domain上下文中定義的變量,自動綁定到domain對象
- 顯式綁定: 把不是在domain上下文中定義的變量,以代碼的方式綁定到domain對象
方法
序號 | 方法 & 描述 |
---|---|
1 |
domain.run(function) 在域的上下文運行提供的函數,隱式的綁定了所有的事件分發器,計時器和底層請求。 |
2 |
domain.add(emitter) 顯式的增加事件 |
3 |
domain.remove(emitter) 刪除事件。 |
4 |
domain.bind(callback) 返回的函數是一個對於所提供的回調函數的包裝函數。當調用這個返回的函數被時,所有被拋出的錯誤都會被導向到這個域的 error 事件。 |
5 |
domain.intercept(callback) 和 domain.bind(callback) 類似。除了捕捉被拋出的錯誤外,它還會攔截 Error 對象作爲參數傳遞到這個函數。 |
6 |
domain.enter() 進入一個異步調用的上下文,綁定到domain。 |
7 |
domain.exit() 退出當前的domain,切換到不同的鏈的異步調用的上下文中。對應domain.enter()。 |
8 |
domain.dispose() 釋放一個domain對象,讓node進程回收這部分資源。 |
9 |
domain.create() 返回一個domain對象。 |
屬性
序號 | 屬性 & 描述 |
---|---|
1 |
domain.members 已加入domain對象的域定時器和事件發射器的數組。 |
實例
創建 main.js 文件,代碼如下所示:
var EventEmitter = require("events").EventEmitter; var domain = require("domain"); var emitter1 = new EventEmitter(); // 創建域 var domain1 = domain.create(); domain1.on('error', function(err){ console.log("domain1 處理這個錯誤 ("+err.message+")"); }); // 顯式綁定 domain1.add(emitter1); emitter1.on('error',function(err){ console.log("監聽器處理此錯誤 ("+err.message+")"); }); emitter1.emit('error',new Error('通過監聽器來處理')); emitter1.removeAllListeners('error'); emitter1.emit('error',new Error('通過 domain1 處理')); var domain2 = domain.create(); domain2.on('error', function(err){ console.log("domain2 處理這個錯誤 ("+err.message+")"); }); // 隱式綁定 domain2.run(function(){ var emitter2 = new EventEmitter(); emitter2.emit('error',new Error('通過 domain2 處理')); }); domain1.remove(emitter1); emitter1.emit('error', new Error('轉換爲異常,系統將崩潰!'));
執行以上代碼,結果如下所示:
監聽器處理此錯誤 (通過監聽器來處理) domain1 處理這個錯誤 (通過 domain1 處理) domain2 處理這個錯誤 (通過 domain2 處理) events.js:72 throw er; // Unhandled 'error' event ^ Error: 轉換爲異常,系統將崩潰! at Object.<anonymous> (/www/node/main.js:40:24) at Module._compile (module.js:456:26) at Object.Module._extensions..js (module.js:474:10) at Module.load (module.js:356:32) at Function.Module._load (module.js:312:12) at Function.Module.runMain (module.js:497:10) at startup (node.js:119:16) at node.js:929:3