Node.js 模块

185 阅读5分钟

fs 文件操作模块

fs 模块可以实现与硬盘的交互,例如文件的创建、删除、重命名、移动,还有文件内容的写入、读取,以及文件夹的相关操作。

文件操作

写入文件

fs 模块写入文件有两种模式,一种是异步模式,一种是同步模式。

直接写入

通过 fs 模块的 writeFile 方法来实现。

// 异步写入
fs.writeFile('./data.txt', 'data', (err) => {
  if (err) {
    console.log('写入失败')
    return
  }
  console.log('写入成功')
})

// 同步写入
fs.writeFileSync('./data.txt', 'data')

image.png

直接写入会将文件原内容覆盖,一般适用于一次性写入的场景。

追加写入文件

可以通过 writeFile 方法的第三个参数来实现追加写入

// 异步写入
fs.writeFile('./data.txt', '\r\n追加写入的内容1', { flag: 'a' }, (err) => {
  if (err) {
    console.log('写入失败')
    return
  }
  console.log('写入成功')
})

// 同步写入
fs.writeFileSync('./data.txt', '\r\n追加写入的内容2', { flag: 'a' })

也可以使用 appendFile 方法来实现

// 异步写入
fs.appendFile('./data.txt', '\r\n追加写入的内容1', (err) => {
  if (err) {
    console.log('写入失败')
    return
  }
  console.log('写入成功')
})

// 同步写入
fs.appendFileSync('./data.txt', '\r\n追加写入的内容2', { flag: 'a' })

image.png

流式写入

除了使用 writeFile 方法来实现文件的写入,我们也可以使用流式写入方法来写入文件。

// 1. 创建写入流对象
const ws = fs.createWriteStream('./诗歌.txt')

// 2. 写入内容
ws.write('第一句\r\n')
ws.write('第二句\r\n')
ws.write('第三句\r\n')
ws.write('第四句\r\n')

// 3. 关闭通道(可选)
ws.close()

image.png

流式写入类似于追加写入。

流式写入方式适用于大文件写入或者频繁写入的场景,writeFile 适合于写入频率较低的场景。

读取文件

// 异步读取
fs.readFile('./data.txt', (err, data) => {
  if (err) {
    console.log('读取失败')
    return
  }
  console.log(data.toString())
})

// 同步读取
const data = fs.readFileSync('./data.txt')
console.log(data.toString())

流式读取:分段读取,每次只读取一定字节的数据

// 1. 创建读取流对象
const rs = fs.createReadStream('./data.txt')

// 2. 监听读取事件
rs.on('data', (chunk) => {
  // 读取出来的数据
  console.log(chunk)
})

// 读取结束事件
rs.on('end', () => {
  console.log('end')
})

不管是哪种读取方式,读出来的都是 Buffer 格式的数据。

文件的移动与重命名

// 移动
fs.rename('./data.txt', './data/index.txt', (err) => {
  console.log(err)
})

// 重命名
fs.rename('./data.txt', './data2.txt', (err) => {
  console.log(err)
})

// 同步操作
fs.renameSync()

文件删除

fs.unlink('./data.txt', (err) => {
  console.log(err)
})

fs.rm('./data.txt', (err) => {
  console.log(err)
})

// 同步操作
fs.unlinkSync()
fs.rmSync()

文件夹操作

创建文件夹

fs.mkdir('./html', err => {
  if (err) {
    console.log('创建失败')
    return
  }
  console.log('创建成功')
})

创建嵌套文件夹

fs.mkdir('./html/a/b', { recursive: true }, err => {
  if (err) {
    console.log('创建失败')
    return
  }
  console.log('创建成功')
})

读取文件夹

fs.readdir('./', (err, data) => {
  if (err) {
    console.log('读取失败')
    return
  }
  console.log(data)
})

删除文件夹

fs.rmdir('./html', (err) => {
  if (err) {
    console.log('删除失败')
    return
  }
  console.log('删除成功')
})

path 路径模块

resolve 方法:拼接绝对路径

path.resolve(__dirname, 'index.html')
// 或者
path.resolve(__dirname, './index.html')

// 不允许
path.resolve(__dirname, '/index.html')

http 服务模块

基本使用

使用 http 模块可以启动一个本地的服务

// 导入 http 模块
const http = require('http')

// 创建一个服务对象
const server = http.createServer((request, response) => {
  // 获取请求方式
  console.log(request.method)
  // 获取请求路径
  console.log(request.url)
  // 获取请求头
  console.log(request.headers)
  
  // 设置响应状态码
  response.statusCode = 200
  // 设置响应头
  response.setHeader('content-type', 'text/html;charset=utf-8')
  // 自定义响应头
  response.setHeader('myHeader', 'abc')
  // 设置多个同名的响应头
  response.setHeader('test', ['a', 'b', 'c'])
  // 设置响应体(返回的数据)
  response.write('你好') 
  response.write('我是') 
  response.end('kobe') // 必须存在且只能存在一个
})

// 监听端口号启动服务,当浏览器对这个服务发送请求时会触发上面的回调函数
server.listen(8000, () => {
  console.log('服务已启动!')
})

使用 node 命令执行以上代码会启动一个本地的服务,此时在浏览器中输入 127.0.0.1:8000,页面上会展示 你好我是kobe

使用 url 模块或 URL 类获取请求路径及参数

当我们在浏览器中输入 http://127.0.0.1:8000/user?name:zs&age=18 向服务发送请求时,我们在服务对象的回调函数中可以获取到请求的路径及参数

// 导入 http 模块
const http = require('http')

// 创建一个服务对象
const server = http.createServer((request, response) => {
  // 获取请求路径
  console.log(request.url) // /user?name:zs&age=18
  
  response.setHeader('content-type', 'text/html;charset=utf-8')
  // 设置响应体
  response.end('你好') 
})

// 监听端口号启动服务,当浏览器对这个服务发送请求时会触发上面的回调函数
server.listen(8000, () => {
  console.log('服务已启动!')
})

但是这个路径是没有经过处理的,我们不能直接进行使用,我们可以使用 url 模块来对其进行处理。

const url = require('url')

const server = http.createServer((request, response) => {
  const { pathname, query } = url.parse(request.url, true)
  console.log(pathname)  // /user
  console.log(query) // { name: 'zs', age: '18' }
  
  response.setHeader('content-type', 'text/html;charset=utf-8')
  // 设置响应体
  response.end('你好') 
})

也可以使用 URL 类来处理

const url = require('url')

const server = http.createServer((request, response) => {
  const { pathname, query } = new URL(request.url, '127.0.0.1')
  console.log(pathname)  // /user
  console.log(query) // 
  
  response.setHeader('content-type', 'text/html;charset=utf-8')
  // 设置响应体
  response.end('你好') 
})

★ 设置静态资源访问

我们可以根据访问的 url 地址来返回不同的静态资源文件。

具体实现思路是,我们将静态资源文件,例如 html 文件,js 文件,css 文件,或者是图片文件都放在某个文件夹下。当浏览器发送请求时我们可以获取到对应的 url 地址,然后拼接上文件夹的路径,通过 fs 模块的文件读取,读取出文件并将其返回。

const url = require('url')
const fs = require('fs')

// 定义 mime 类型
let mimes = {}

const server = http.createServer((request, response) => {
  // 获取请求的路径
  const { pathname } = new URL(request.url, 'http://127.0.0.1')
  // 设置页面根目录
  const root = __dirname + '/page'
  // 拼接文件读取的路径
  let filename
  if (pathname === '/') {
    // 如果没有写路径,默认读取页面根目录下的 index.html 文件
    filename = root + '/index.html'
  } else {
    filename = root + pathname
  }
  
  // 读取文件
  fs.readFile(filename, (err, data) => {
    // 错误处理
    if (err) {
      // 设置字符集,解决文件乱码问题
      response.setHeader('content-type', 'text/html;charset=utf-8')
      
      // 根据不同错误返回不同状态码及结果
      switch (err.code) {
        case 'ENOENT':
          response.statusCode = 404
          response.end('<h1>404 NOT FOUND</h1>')
        default:
          response.statusCode = 500 
          response.end('<h1>500</h1>')
      }
      
      return
    }
    // 设置 mime 类型
    let ext = path.extname(filename).slice(1)
    let type = mimes[ext]
    if (type) {
      if (ext === 'html') {
        response.setHeader('content-type', type + ';charset=utf-8')
      } else {
        response.setHeader('content-type', type)
      }
    } else {
      response.setHeader('content-type', 'application/octet-stream')
    }
    
    response.end(data)
  })
})

相对路径与绝对路径

网页中的 url 分为两种:相对路径与绝对路径

绝对路径

绝对路径分为三种

形式:

相对路径

相对当前页面所在文件进行计算

形式:./login/index.js./admin/index.jslogin/index.jsadmin/index.js