Express - 第三方中间件

61 阅读4分钟

第三方中间件 和 Express内置中间件一样,都通过use进行安装

注册方式都是函数,函数的返回值是对应的中间件函数,之所以定义为函数,是为了方便传入配置信息

日志记录

Morgan => Express 官方提供的日志记录中间件

但并没有被内置集成,需要手动安装

安装

npm install morgan

使用

import express from 'express'
import morgan from 'morgan'
import fs from 'fs'const app = express()
​
// 使用 morgan 中间件 记录请求日志
app.use(morgan('combined', {
  // 默认日志输出到 console
  // 设置 stream 后,日志输出到文件
  stream: fs.createWriteStream('./logs/access.log', { flags: 'a' })
}))
​
app.post('/login', (req, res) => {
  res.send('login success')
})
​
app.listen(3000, () => {
  console.log('Server is running on port 3000')
})

文件上传

使用 multer

单个文件

import express from 'express'
import multer from 'multer'// 生成一个 multer 实例
// 参数 desc 是 destination的简写,即指定文件存储路径
const upload = multer({ dest: 'uploads/' })
​
const app = express()
​
// 仅在 /upload 路径下,使用 multer 中间件
// 1. upload.single(<字段名>) 解析单个文件
app.post('/upload', upload.single('avatar'), (req, res) => {
  // 2. 处理后的文件相关元信息会被挂载到 req.file 上
  console.log(req.file)
  /*
    {
      fieldname: 'avatar',
      originalname: 'js.png',
      encoding: '7bit',
      mimetype: 'image/png',
      destination: 'uploads/',
      // 注意: multer 会自动生成文件名,但是没有后缀名
      // 所以会导致 vscode 默认无法打开该文件
      filename: '63637f6b29c6d78ffd0a85663a584f88',
      path: 'uploads/63637f6b29c6d78ffd0a85663a584f88',
      size: 4602
    }
  */
​
  // 表单上传时,非文件字段会挂载到 req.body 上
  // 例如传递了 字符串类型的 username 字段 和 文件类型的 avatar 字段
  // 那么 req.body 会存在 username 字段,而不存在 avatar 字段
  console.log(req.body)
  res.send('upload success')
})
​
app.listen(3000, () => {
  console.log('Server is running on port 3000')
})
import express from 'express'
import multer from 'multer'
import path from 'node:path'const storage = multer.diskStorage({
  destination: function (req, file, cb) {
    // dest 指定的文件存储路径,不存在 multer会帮助你进行创建
    // 而如果使用 storage 选项,则需要自己进行创建,multer默认不会帮你进行创建
    cb(null, './uploads')
  },
  filename: function (req, file, cb) {
    cb(null, file.fieldname + '-' + Date.now() + path.extname(file.originalname))
  }
})
​
// dest 是字符串类型值,表示文件存储路径
// 而如果需要更粒度化的控制,比如设置文件名等,则需要使用 storage 选项 替代 dest 选项
const upload = multer({ storage })
​
const app = express()
​
app.post('/upload', upload.single('avatar'), (req, res) => {
  res.send('upload success')
})
​
app.listen(3000, () => {
  console.log('Server is running on port 3000')
})

多个文件

import express from 'express'
import multer from 'multer'
import path from 'node:path'const storage = multer.diskStorage({
  destination: function (req, file, cb) {
    cb(null, './uploads')
  },
  filename: function (req, file, cb) {
    cb(null, file.fieldname + '-' + Date.now() + path.extname(file.originalname))
  }
})
​
const upload = multer({ storage })
​
const app = express()
​
// 上传多个文件,字段名为avatar,对应文件最大数为2
// 最大上传的文件数量是可以省略的
app.post('/upload', upload.array('avatar', 2), (req, res) => {
  // 对应文件元信息会以数组形式被挂载到req.files上
  console.log(req.files)
  res.send('upload success')
})
​
app.listen(3000, () => {
  console.log('Server is running on port 3000')
})
import express from 'express'
import multer from 'multer'
import path from 'node:path'const storage = multer.diskStorage({
  destination: function (req, file, cb) {
    cb(null, './uploads')
  },
  filename: function (req, file, cb) {
    cb(null, file.fieldname + '-' + Date.now() + path.extname(file.originalname))
  }
})
​
const upload = multer({ storage })
​
const app = express()
​
// 同时设置多个文件字段,并限制文件数量
app.post(
  '/upload',
  upload.fields([{ name: 'gallery', maxCount: 8 }, { name: 'avatar', maxCount: 1 }]),
  (req, res) => {
    // 此时 req.files 的类型是 Record<key, 文件的元信息[] >
    console.log(req.files)
    res.send('upload success')
  }
)
​
app.listen(3000, () => {
  console.log('Server is running on port 3000')
})

接收一切文件

import express from 'express'
import multer from 'multer'
import path from 'node:path'const storage = multer.diskStorage({
  destination: function (req, file, cb) {
    cb(null, './uploads')
  },
  filename: function (req, file, cb) {
    cb(null, file.fieldname + '-' + Date.now() + path.extname(file.originalname))
  }
})
​
const upload = multer({ storage })
​
const app = express()
​
// upload.single、 upload.array、upload.fields 是处理单个和多个文件上传的中间件
// + 此时二进制文件对应key必须指定,否则会报错
// upload.any 则表示接收一切字段
app.use(upload.any())
​
app.post('/form', (req, res) => {
  // 非二进制内容会被挂载到 req.body 上
  console.log(req.body)
  // 二进制内容会被挂载到 req.files 上,以数组形式呈现
  console.log(req.files)
  res.send('upload success')
})
​
app.listen(3000, () => {
  console.log('Server is running on port 3000')
})

接收非文件表单数据

import express from 'express'
import multer from 'multer'const upload = multer()
​
const app = express()
​
// upload.none() 表示不处理文件上传,只处理表单数据
// form-data 格式 一般用于上传文件,如果单纯需要传递表单数据,推荐使用 application/json 格式// 解析 form-data 格式不一定是某个具体接口才需要的功能,是所有接口都需要的功能,所以需要全局使用
app.use(upload.none())
​
app.post('/form', (req, res) => {
  // 对应字段会以对象形式被保存到 req.body 上
  console.log(req.body)
  res.send('upload success')
})
​
app.listen(3000, () => {
  console.log('Server is running on port 3000')
})