思维导图

构建前端

1. 安装项目

npm create vite@latest

相信大家运行个项目没啥问题吧,这里作者就不多费口舌了

2. 安装ant-design-vue

npm install ant-design-vue@4.x --save

不用安装这个也可以,但是要自己写前端上传代码,没必要,我们就站在巨人肩膀上就行

3. 引入ant-design-vue

直接在main.ts中进行全局引入

import './assets/main.css'
import 'ant-design-vue/dist/reset.css';
import Antd from 'ant-design-vue';

import { createApp } from 'vue'
import App from './App.vue'

const app = createApp(App);

app.use(Antd).mount('#app');

然后直接使用

<template>
  <a-upload
    v-model:file-list="fileList"
    name="avatar"
    action="http://localhost:3000/upload"
    :headers="headers"
    :progress="progress"
    @change="handleChange"
  >
    <a-button>
      <upload-outlined></upload-outlined>
      Click to Upload
    </a-button>
  </a-upload>
</template>
<script lang="ts" setup>
import { message } from 'ant-design-vue';
import { UploadOutlined } from '@ant-design/icons-vue';
import { ref } from 'vue';
import type { UploadChangeParam, UploadProps } from 'ant-design-vue';
const handleChange = (info: UploadChangeParam) => {
  if (info.file.status !== 'uploading') {
    console.log(info.file, info.fileList);
  }
  if (info.file.status === 'done') {
    message.success(`${info.file.name} file uploaded successfully`);
  } else if (info.file.status === 'error') {
    message.error(`${info.file.name} file upload failed.`);
  }
};

const fileList = ref([]);
const progress: UploadProps['progress'] = {
  strokeColor: {
    '0%': '#108ee9',
    '100%': '#87d068',
  },
  strokeWidth: 3,
  format: percent => `${parseFloat(percent.toFixed(2))}%`,
  class: 'test',
};
const headers = { authorization: 'authorization-text' };
</script>

需要注意的点

  1. name中的avatar是后端接收文件的字段名
  2. action是具体的后端接口地址
  3. headers中的authorization是前端传给后端的头部信息

详细的信息请查看官网: https://www.antdv.com/components/overview

构建后端

1. 安装项目

express myapp

如果没有安装express,可以先安装express

npm install -g express-generator

2. 安装crypto、multer

npm i crypto multer -S

3. 后端路由

var express = require('express');
var router = express.Router();
const path = require('path');
const crypto = require('crypto'); // 加密
// 引入multer
const multer  = require('multer')
// 定义一个生成唯一哈希文件名的函数
function generateHashedFilename(req, file, callback) {
  const hash = crypto.randomBytes(16).toString('hex');
  const ext = path.extname(file.originalname); // 获取原始文件扩展名
  const filename = `${hash}${ext}`; // 将哈希与扩展名拼接成新的文件名
  callback(null, filename);
}

const storage = multer.diskStorage({
  destination: function (req, file, cb) {
    cb(null, 'public/images/');
  },
  filename: generateHashedFilename,
});

const upload = multer({ storage })

/* GET home page. */
router.get('/', function(req, res, next) {
  res.render('index', { title: 'Express' });
});

router.post('/upload',upload.single('avatar'), function(req, res, next) {
  res.send('恭喜上传成功');
  // console.log(req.file);
});

module.exports = router;

说明

  1. cb(null, ‘public/images/‘); 这个是将文件保存到public/images/目录下
  2. upload.single(‘avatar’)是前端传过来的avatar字段名,这个字段名在前端的name属性中定义的

4. 解决跨域

安装cors

npm install cors -S

在app.js中添加

var cors = require('cors');

// 解决跨域问题
app.use(cors({
  origin: 'http://127.0.0.1:5173', // 允许指定源进行跨域访问,也可以设置为'*'表示任何源
  credentials: false, // 如果需要携带cookie,开启此项
  allowedHeaders: ['x-requested-with','authorization'] // 允许自定义请求头
}));

说明

  1. origin是前端实际地址
  2. 记得放在路由之前,不然会报错

总结

这里就只对单文件上传进行简单的讲解,关于文件上传还有很多的逻辑,比如:

  1. 文件大小限制
  2. 文件类型限制
  3. 支持文件夹上传
  4. 大文件分片上传
  5. 多文件上传等等;

大家可以参考ant-design-vuemulter官网,或者网上找找资料