VUE3 + Element Plus + express + mongodb 上传图片

282 阅读1分钟

template

<el-upload
  :action="url + ':' + port + '/upload'"
  :data="{type: 'avatar'}"
  :headers="{'Authorization': token}"
  :on-success="handleSuccess"
  :on-error="handleError"
  :show-file-list="false"
>
  <el-button type="primary">上传</el-button>
</el-upload>

script setup

const url = import.meta.env.VITE_API_BASE_URL;
const port = import.meta.env.VITE_API_PORT;
const token = localStorage.getItem('token');

// 显示的图片地址
let avatar = ref('https://cube.elemecdn.com/3/7c/3ea6beec64369c2642b92c6726f1epng.png');  

function handleSuccess(response, uploadFile, uploadFiles) {
  avatar.value = url + ':' + port + '/images/' + response;  // 成功后换新图片
}
function handleError(error, uploadFile, uploadFiles) {
  // 这里拦截了,axios的拦截就不起效了
  if (/401/.test(error.toString())) {
    // 过期了 
    ElMessage.error('登录已经超时,请先登录!')
    router.push('/');
    return;
  }
}

node部分 upload.js

// 数据库
const Mongodb = require('../mongodb');
const db = new Mongodb();
const mongoose = require('mongoose');

// 解析 token 的
const token = require('../utils/token');

// 导入 express
const express = require('express');

// 创建路由器对象
const router = express.Router();

const fs = require('fs');
const multer = require('multer');
// Multer 是一个 node.js 中间件,用于处理 `multipart/form-data` 类型的表单数据
// Multer 不会处理任何非 `multipart/form-data` 类型的表单数据

router.post('/upload', multer().single('file'), async (req, res) => {
  const { buffer, mimetype, size } = req.file;
  
  // 解决originalname中文乱码,originalname是原来的文件名
  const originalname = Buffer.from(req.file.originalname, 'latin1').toString('utf-8');
  
  // 生成保存的文件名和类型
  const fileName = (new Date()).getTime() + parseInt(Math.random() * 3435) + parseInt(Math.random() * 6575);
  const fileType = mimetype.split('/')[1];
  const fullName = fileName+'.'+fileType;
  
  const { type } = req.body;
  // req.body里存着和图片一起传来的数据
  
  const { id } = await token.parseToken(req.header('Authorization'));
  const oid = new mongoose.Types.ObjectId(id);
  
  fs.writeFile('public/images/' + fullName, buffer, e => {
    if (e) {
      console.log('上传失败:',e)
      return res.send(500);
    }
    // 保存成功后把保存的文件名存起来
    db.updateOne('users', {_id: oid}, {$set:{'avatar': fullName}})
    .then(() => {
      res.status(200);
      res.send(fullName);
    })
    .catch(() => {
      res.status(500);
      res.send('修改失败');
    })
  })
})