我们知道 nuxt3
是一个全栈框架, 可以单纯的只写前端,也可以写后端接口, 今天我们使用 nuxt3写一个 文件上传接口
在 express
中,我们需要借助 multer
等 包进行文件文件上传操作, 我们看看 nuxt3
可以怎么处理
安装依赖
pnpm add uuid -S
为了防止前端上传的文件名 重名覆盖的问题,这里使用 uuid
生成文件名
我们将上传后的文件,写入到 public/uploads
目录, 请提前创建好 这个目录
代码实现
-
在
server/api
下面创建一个upload.ts
文件, 这个就是一个接口 -
创建接口的基础雏形
export default defineEventHandler(async (event) => {
... 业务代码
})
这里其实没有看到 GET
, POST
等请求方式的区分,你可以理解为 express
的 all
只要请求地址 http://localhost:3000/api/upload
都会走这里, 不区分 method
- 写代码
- 使用流和管道 进行文件的读写
- 使用 readMultipartFormData API 读取 body中的表单内容, readMultipartFormData 是
h3
提供的,在nuxt3
中属于全局的API - 支持多文件上传
import { createWriteStream } from 'node:fs'
import { fileURLToPath } from 'url'
import { pipeline, PassThrough } from 'node:stream'
import { v4 as uuidV4 } from 'uuid'
import path from 'path'
const __filename = fileURLToPath(import.meta.url)
const __dirname = path.dirname(__filename)
/**
* 支持多个文件上传
*/
export default defineEventHandler(async (event) => {
// 使用 表单上传文件, readBody是不能解析的,它解析的是 json 格式的数据
// let r1 = await readBody(event)
const form = await readMultipartFormData(event)
// form-data 里面什么都没有,这里form解析的就是 undefined
if (!form) {
return {
code: 1000,
data: null,
message: '上传文件不存在'
}
}
const allFiles = form.filter((item) => item.type)
let filePromise = allFiles.map((item) => {
let filename = uuidV4() + path.parse(item!.filename!).ext
// 创建写的文件流
const filePath = path.resolve(__dirname, '../../', `public/uploads/${filename}`)
const wirteStream = createWriteStream(filePath)
let data = item.data as Buffer
// 创建一个可读流, item.data 是一个Buffer
const readStream = new PassThrough().end(data)
return new Promise((resolve, reject) => {
pipeline(readStream, wirteStream, (err) => {
if (err) {
reject(err)
console.log('报错了')
console.log(err)
return
}
resolve({
url: `http://localhost:3000/uploads/${filename}`,
type: item.type
})
})
})
})
try {
let res = await Promise.all(filePromise)
return {
code: 0,
data: res,
message: '上传成功'
}
} catch (error: any) {
console.log('文件上传报错')
console.log(error)
return {
code: 1000,
data: null,
message: '上传失败' + error.message
}
}
})
测试
是不是相当的简单。
参考资料
- h3 - The Web Framework for Modern JavaScript Era (unjs.io) h3 获取请求体内容 API地址