前端
前端使用的是vue3+element-plus
使用element-plus中的upload组件
使用组件的自定义请求http-request
template
<el-upload
class="avatar-uploader"
:show-file-list="false"
:on-success="handleAvatarSuccess"
:before-upload="handleAvatarBefore"
:http-request="httpRequestSelf">
<img v-if="imageUrl" width="100" :src="imageUrl" class="avatar"/>
<el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>
</el-upload>
<script setup lang="ts"> 代码
const imageUrl = ref('')
// 上传成功 拿到uploadsImg接口返回的数据
const handleAvatarSuccess: UploadProps['onSuccess'] = (
response,
uploadFile,
uploadFileList
) => {
//拿到返回的图片路径后 赋值
imageUrl.value = response.data.filepath;
}
// 上传图片之前的配置
const handleAvatarBefore = (rawFile: UploadRawFile):boolean => {
// if (rawFile.type !== 'image/jpeg') {
// ElMessage.error('Avatar picture must be JPG format!')
// return false
// } else if (rawFile.size / 1024 / 1024 > 2) {
// ElMessage.error('Avatar picture size can not exceed 2MB!')
// return false
// }
return true
}
//请求 上传图片 返回路径
const httpRequestSelf = (options: UploadRequestOptions):XMLHttpRequest | Promise<unknown> => {
let params = new FormData()
//注意 img 文件名
params.append("img", options.file);
return uploadsImg(params).then(res => {
options.onSuccess(res);
})
}
注意前端接口请求格式
uploadsImg = (data:object) => {
return axios.request({
url:"/uploadsImg",
method:"post",
data:data,
headers: {
'content-type': 'multipart/form-data'
}
})
}
后端
后端使用的是nodeJS+Koa2
接收前端传过来的数据 我们需要用到koa-body
需要先下载依赖 npm install koa koa-router koa-body
index.js
const Koa = require("koa")
const app = new Koa();
const Router = require("koa-router")
const router = new Router();
const path = require('path');
const {koaBody} = require('koa-body');
app.use(
koaBody({
multipart: true,
patchKoa:true,
formidable:{
keepExtensions:true,//保留文件后缀
// uploadDir: path.resolve(__dirname, '../public/uploads'),
patchKoa:true,
maxFieldsSize: 10 * 1024 * 1024, // 文件上传大小限制
onFileBegin: (name, file) => { //文件上传前的配置
// 无论是多文件还是单文件上传都会重复调用此函数
// 最终要保存到的文件夹目录
// const dirName = format(new Date(), "yyyyMMddhhmmss");
const dir = path.resolve(__dirname, `../public/uploads/${name}`);
// // 检查文件夹是否存在如果不存在则新建文件夹
if (!fs.existsSync(dir)) {
fs.mkdirSync(dir);
}
// // 文件名称去掉特殊字符但保留原始文件名称
// const fileName = file.name
// .replaceAll(" ", "_")
// .replace(/[`~!@#$%^&*()|\-=?;:'",<>\{\}\\\/]/gi, "_");
// file.name = fileName;
// 覆盖文件存放的完整路径(保留原始名称)
if(name == 'img'){
file.filepath= `${dir}/${file.newFilename}`;
}else if (name=='video'){
file.filepath= `${dir}/${file.newFilename}`;
}
},
onError(err){
console.log(err)
}
}
})
);
router.post("/uploadsImg",(ctx) => {
ctx.response.body = ctx.request.files; //返回响应数据
});
app.use(router);
app.listen(3000,()=>{
console.log('3000端口启动')
})