第三方中间件 和 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')
})