一.Nodejs文件系统模块
fs
模块提供了许多非常实用的函数来访问文件系统并与文件系统进行交互。
无需安装。 作为 Node.js 核心的组成部分,可以通过简单地引用来使用它:
const fs = require('fs')
一旦这样做,就可以访问其所有的方法,包括:
fs.access()
: 检查文件是否存在,以及 Node.js 是否有权限访问。fs.appendFile()
: 追加数据到文件。如果文件不存在,则创建文件。fs.chmod()
: 更改文件(通过传入的文件名指定)的权限。相关方法:fs.lchmod()
、fs.fchmod()
。fs.chown()
: 更改文件(通过传入的文件名指定)的所有者和群组。相关方法:fs.fchown()
、fs.lchown()
。fs.close()
: 关闭文件描述符。fs.copyFile()
: 拷贝文件。fs.createReadStream()
: 创建可读的文件流。fs.createWriteStream()
: 创建可写的文件流。fs.link()
: 新建指向文件的硬链接。fs.mkdir()
: 新建文件夹。fs.mkdtemp()
: 创建临时目录。fs.open()
: 设置文件模式。fs.readdir()
: 读取目录的内容。fs.readFile()
: 读取文件的内容。相关方法:fs.read()
。fs.readlink()
: 读取符号链接的值。fs.realpath()
: 将相对的文件路径指针(.
、..
)解析为完整的路径。fs.rename()
: 重命名文件或文件夹。fs.rmdir()
: 删除文件夹。fs.stat()
: 返回文件(通过传入的文件名指定)的状态。相关方法:fs.fstat()
、fs.lstat()
。fs.symlink()
: 新建文件的符号链接。fs.truncate()
: 将传递的文件名标识的文件截断为指定的长度。相关方法:fs.ftruncate()
。fs.unlink()
: 删除文件或符号链接。fs.unwatchFile()
: 停止监视文件上的更改。fs.utimes()
: 更改文件(通过传入的文件名指定)的时间戳。相关方法:fs.futimes()
。fs.watchFile()
: 开始监视文件上的更改。相关方法:fs.watch()
。fs.writeFile()
: 将数据写入文件。相关方法:fs.write()
。
关于 fs
模块的特殊之处是,所有的方法默认情况下都是异步的,但是通过在前面加上 Sync
也可以同步地工作。
例如:
fs.rename()
fs.renameSync()
fs.write()
fs.writeSync()
这在应用程序流程中会产生巨大的差异。
Node.js 10 包含了对基于 promise API 的实验性支持。
例如,试验一下 fs.rename()
方法。 异步的 API 会与回调一起使用:
const fs = require('fs')
fs.rename('before.json', 'after.json', err => {
if (err) {
return console.error(err)
}
//完成
})
同步的 API 则可以这样使用,并使用 try/catch 块来处理错误:
const fs = require('fs')
try {
fs.renameSync('before.json', 'after.json')
//完成
} catch (err) {
console.error(err)
}
此处的主要区别在于,在第二个示例中,脚本的执行会阻塞,直到文件操作成功。
二.Nodejs 路径模块
path.basename()
path.dirname()
path.extname()
path.isAbsolute()
path.join()
path.normalize()
path.parse()
path.relative()
path.resolve()
path
模块提供了许多非常实用的函数来访问文件系统并与文件系统进行交互。
无需安装。 作为 Node.js 核心的组成部分,可以通过简单地引用来使用它:
const path = require('path')
该模块提供了 path.sep
(作为路径段分隔符,在 Windows 上是 \
,在 Linux/macOS 上是 /
)和 path.delimiter
(作为路径定界符,在 Windows 上是 ;
,在 Linux/macOS 上是 :
)。
还有这些 path
方法:
path.basename()
返回路径的最后一部分。 第二个参数可以过滤掉文件的扩展名:
require('path').basename('/test/something') //something
require('path').basename('/test/something.txt') //something.txt
require('path').basename('/test/something.txt', '.txt') //something
path.dirname()
返回路径的目录部分:
require('path').dirname('/test/something') // /test
require('path').dirname('/test/something/file.txt') // /test/something
path.extname()
返回路径的扩展名部分。
require('path').extname('/test/something') // ''
require('path').extname('/test/something/file.txt') // '.txt'
path.isAbsolute()
如果是绝对路径,则返回 true。
require('path').isAbsolute('/test/something') // true
require('path').isAbsolute('./test/something') // false
path.join()
连接路径的两个或多个部分:
const name = 'joe'
require('path').join('/', 'users', name, 'notes.txt') //'/users/joe/notes.txt'
path.normalize()
当包含类似 .
、..
或双斜杠等相对的说明符时,则尝试计算实际的路径:
require('path').normalize('/users/joe/..//test.txt') //'/users/test.txt'
path.parse()
解析对象的路径为组成其的片段:
root
: 根路径。dir
: 从根路径开始的文件夹路径。base
: 文件名 + 扩展名name
: 文件名ext
: 文件扩展名
例如:
require('path').parse('/users/test.txt')
结果是:
{
root: '/',
dir: '/users',
base: 'test.txt',
ext: '.txt',
name: 'test'
}
path.relative()
接受 2 个路径作为参数。 基于当前工作目录,返回从第一个路径到第二个路径的相对路径。
例如:
require('path').relative('/Users/joe', '/Users/joe/test.txt') //'test.txt'
require('path').relative('/Users/joe', '/Users/joe/something/test.txt') //'something/test.txt'
path.resolve()
可以使用 path.resolve()
获得相对路径的绝对路径计算:
path.resolve('joe.txt') //'/Users/joe/joe.txt' 如果从主文件夹运行
通过指定第二个参数,resolve
会使用第一个参数作为第二个参数的基准:
path.resolve('tmp', 'joe.txt') //'/Users/joe/tmp/joe.txt' 如果从主文件夹运行
如果第一个参数以斜杠开头,则表示它是绝对路径:
path.resolve('/etc', 'joe.txt') //'/etc/joe.txt'
三.Nodejs事件模块
emitter.addListener()
emitter.emit()
emitter.eventNames()
emitter.getMaxListeners()
emitter.listenerCount()
emitter.listeners()
emitter.off()
emitter.on()
emitter.once()
emitter.prependListener()
emitter.prependOnceListener()
emitter.removeAllListeners()
emitter.removeListener()
emitter.setMaxListeners()
events
模块为提供了 EventEmitter 类,这是在 Node.js 中处理事件的关键。
const EventEmitter = require('events')
const door = new EventEmitter()
事件监听器返回及使用以下事件:
- 当监听器被添加时返回
newListener
。 - 当监听器被移除时返回
removeListener
。
以下是最常用的方法的详细说明:
emitter.addListener()
emitter.on()
的别名。
emitter.emit()
触发事件。 按照事件被注册的顺序同步地调用每个事件监听器。
door.emit("slam") // 触发 "slam" 事件。
emitter.eventNames()
返回字符串(表示在当前 EventEmitter
对象上注册的事件)数组:
door.eventNames()
emitter.getMaxListeners()
获取可以添加到 EventEmitter
对象的监听器的最大数量(默认为 10,但可以使用 setMaxListeners()
进行增加或减少)。
door.getMaxListeners()
emitter.listenerCount()
获取作为参数传入的事件监听器的计数:
door.listenerCount('open')
emitter.listeners()
获取作为参数传入的事件监听器的数组:
door.listeners('open')
emitter.off()
emitter.removeListener()
的别名,新增于 Node.js 10。
emitter.on()
添加当事件被触发时调用的回调函数。
用法:
door.on('open', () => {
console.log('打开')
})
emitter.once()
添加当事件在注册之后首次被触发时调用的回调函数。 该回调只会被调用一次,不会再被调用。
const EventEmitter = require('events')
const ee = new EventEmitter()
ee.once('my-event', () => {
//只调用一次回调函数。
})
emitter.prependListener()
当使用 on
或 addListener
添加监听器时,监听器会被添加到监听器队列中的最后一个,并且最后一个被调用。 使用 prependListener
则可以在其他监听器之前添加并调用。
emitter.prependOnceListener()
当使用 once
添加监听器时,监听器会被添加到监听器队列中的最后一个,并且最后一个被调用。 使用 prependOnceListener
则可以在其他监听器之前添加并调用。
emitter.removeAllListeners()
移除 EventEmitter
对象的所有监听特定事件的监听器:
door.removeAllListeners('open')
emitter.removeListener()
移除特定的监听器。 可以通过将回调函数保存到变量中(当添加时),以便以后可以引用它:
const doSomething = () => {}
door.on('open', doSomething)
door.removeListener('open', doSomething)
emitter.setMaxListeners()
设置可以添加到 EventEmitter
对象的监听器的最大数量(默认为 10,但可以增加或减少)。
door.setMaxListeners(50)
四.Node.js http 模块
目录
HTTP 核心模块是 Node.js 网络的关键模块。
可以使用以下代码引入:
const http = require('http')
该模块提供了一些属性、方法、以及类。
属性
http.METHODS
此属性列出了所有支持的 HTTP 方法:
> require('http').METHODS
[ 'ACL',
'BIND',
'CHECKOUT',
'CONNECT',
'COPY',
'DELETE',
'GET',
'HEAD',
'LINK',
'LOCK',
'M-SEARCH',
'MERGE',
'MKACTIVITY',
'MKCALENDAR',
'MKCOL',
'MOVE',
'NOTIFY',
'OPTIONS',
'PATCH',
'POST',
'PROPFIND',
'PROPPATCH',
'PURGE',
'PUT',
'REBIND',
'REPORT',
'SEARCH',
'SUBSCRIBE',
'TRACE',
'UNBIND',
'UNLINK',
'UNLOCK',
'UNSUBSCRIBE' ]
http.STATUS_CODES
此属性列出了所有的 HTTP 状态代码及其描述:
> require('http').STATUS_CODES
{ '100': 'Continue',
'101': 'Switching Protocols',
'102': 'Processing',
'200': 'OK',
'201': 'Created',
'202': 'Accepted',
'203': 'Non-Authoritative Information',
'204': 'No Content',
'205': 'Reset Content',
'206': 'Partial Content',
'207': 'Multi-Status',
'208': 'Already Reported',
'226': 'IM Used',
'300': 'Multiple Choices',
'301': 'Moved Permanently',
'302': 'Found',
'303': 'See Other',
'304': 'Not Modified',
'305': 'Use Proxy',
'307': 'Temporary Redirect',
'308': 'Permanent Redirect',
'400': 'Bad Request',
'401': 'Unauthorized',
'402': 'Payment Required',
'403': 'Forbidden',
'404': 'Not Found',
'405': 'Method Not Allowed',
'406': 'Not Acceptable',
'407': 'Proxy Authentication Required',
'408': 'Request Timeout',
'409': 'Conflict',
'410': 'Gone',
'411': 'Length Required',
'412': 'Precondition Failed',
'413': 'Payload Too Large',
'414': 'URI Too Long',
'415': 'Unsupported Media Type',
'416': 'Range Not Satisfiable',
'417': 'Expectation Failed',
'418': 'I\'m a teapot',
'421': 'Misdirected Request',
'422': 'Unprocessable Entity',
'423': 'Locked',
'424': 'Failed Dependency',
'425': 'Unordered Collection',
'426': 'Upgrade Required',
'428': 'Precondition Required',
'429': 'Too Many Requests',
'431': 'Request Header Fields Too Large',
'451': 'Unavailable For Legal Reasons',
'500': 'Internal Server Error',
'501': 'Not Implemented',
'502': 'Bad Gateway',
'503': 'Service Unavailable',
'504': 'Gateway Timeout',
'505': 'HTTP Version Not Supported',
'506': 'Variant Also Negotiates',
'507': 'Insufficient Storage',
'508': 'Loop Detected',
'509': 'Bandwidth Limit Exceeded',
'510': 'Not Extended',
'511': 'Network Authentication Required' }
http.globalAgent
指向 Agent 对象的全局实例,该实例是 http.Agent
类的实例。
用于管理 HTTP 客户端连接的持久性和复用,它是 Node.js HTTP 网络的关键组件。
稍后会在 http.Agent
类的说明中提供更多描述。
方法
http.createServer()
返回 http.Server
类的新实例。
用法:
const server = http.createServer((req, res) => {
//使用此回调处理每个单独的请求。
})
http.request()
发送 HTTP 请求到服务器,并创建 http.ClientRequest
类的实例。
http.get()
类似于 http.request()
,但会自动地设置 HTTP 方法为 GET,并自动地调用 req.end()
。
类
HTTP 模块提供了 5 个类:
http.Agent
http.ClientRequest
http.Server
http.ServerResponse
http.IncomingMessage
http.Agent
Node.js 会创建 http.Agent
类的全局实例,以管理 HTTP 客户端连接的持久性和复用,这是 Node.js HTTP 网络的关键组成部分。
该对象会确保对服务器的每个请求进行排队并且单个 socket 被复用。
它还维护一个 socket 池。 出于性能原因,这是关键。
http.ClientRequest
当 http.request()
或 http.get()
被调用时,会创建 http.ClientRequest
对象。
当响应被接收时,则会使用响应(http.IncomingMessage
实例作为参数)来调用 response
事件。
返回的响应数据可以通过以下两种方式读取:
- 可以调用
response.read()
方法。 - 在
response
事件处理函数中,可以为data
事件设置事件监听器,以便可以监听流入的数据。
http.Server
当使用 http.createServer()
创建新的服务器时,通常会实例化并返回此类。
拥有服务器对象后,就可以访问其方法:
close()
停止服务器不再接受新的连接。listen()
启动 HTTP 服务器并监听连接。
http.ServerResponse
由 http.Server
创建,并作为第二个参数传给它触发的 request
事件。
通常在代码中用作 res
:
const server = http.createServer((req, res) => {
//res 是一个 http.ServerResponse 对象。
})
在事件处理函数中总是会调用的方法是 end()
,它会关闭响应,当消息完成时则服务器可以将其发送给客户端。 必须在每个响应上调用它。
以下这些方法用于与 HTTP 消息头进行交互:
getHeaderNames()
获取已设置的 HTTP 消息头名称的列表。getHeaders()
获取已设置的 HTTP 消息头的副本。setHeader('headername', value)
设置 HTTP 消息头的值。getHeader('headername')
获取已设置的 HTTP 消息头。removeHeader('headername')
删除已设置的 HTTP 消息头。hasHeader('headername')
如果响应已设置该消息头,则返回 true。headersSent()
如果消息头已被发送给客户端,则返回 true。
在处理消息头之后,可以通过调用 response.writeHead()
(该方法接受 statusCode 作为第一个参数,可选的状态消息和消息头对象)将它们发送给客户端。
若要在响应正文中发送数据给客户端,则使用 write()
。 它会发送缓冲的数据到 HTTP 响应流。
如果消息头还未被发送,则使用 response.writeHead()
会先发送消息头,其中包含在请求中已被设置的状态码和消息,可以通过设置 statusCode
和 statusMessage
属性的值进行编辑:
response.statusCode = 500
response.statusMessage = '内部服务器错误'
http.IncomingMessage
http.IncomingMessage
对象可通过以下方式创建:
http.Server
,当监听request
事件时。http.ClientRequest
,当监听response
事件时。
它可以用来访问响应:
- 使用
statusCode
和statusMessage
方法来访问状态。 - 使用
headers
方法或rawHeaders
来访问消息头。 - 使用
method
方法来访问 HTTP 方法。 - 使用
httpVersion
方法来访问 HTTP 版本。 - 使用
url
方法来访问 URL。 - 使用
socket
方法来访问底层的 socket。
因为 http.IncomingMessage
实现了可读流接口,因此数据可以使用流访问。