实现前端文件上传功能并存储到本地MySQL数据库

        在这篇文章中,我们将探讨如何实现一个文件上传功能,并将上传的文件信息存储到本地的MySQL数据库中。我们将使用Vue.js作为前端框架,Node.js和Express作为后端框架,并使用MySQL作为数据库。

项目结构

首先,我们定义项目的基本结构如下:

my-app/
├── backend/
│   ├── models/
│   │   ├── db.js
│   │   ├── fileModel.js
│   ├── routes/
│   │   ├── upload.js
│   ├── uploads/
│   ├── app.js
│   ├── package.json
├── public/
│   ├── index.html
├── src/
│   ├── components/
│   │   ├── FileUpload.vue
│   ├── App.vue
│   ├── main.js
├── package.json

 

后端实现

1. 创建Node.js后端

backend/package.json

        首先,我们需要安装一些必要的依赖包,如expressmysql2sequelizemulter。创建package.json文件,并添加以下内容:

{
  "name": "backend",
  "version": "1.0.0",
  "main": "app.js",
  "dependencies": {
    "body-parser": "^1.19.0",
    "express": "^4.17.1",
    "mysql2": "^2.3.3",
    "sequelize": "^6.6.5",
    "multer": "^1.4.2"
  },
  "scripts": {
    "start": "node app.js"
  }
}

backend/app.js

创建app.js文件,设置Express服务器,并连接到MySQL数据库:

const express = require('express');
const bodyParser = require('body-parser');
const uploadRoute = require('./routes/upload');
const path = require('path');
const db = require('./models/db');

const app = express();
const PORT = 5000;

// 连接到MySQL数据库
db.authenticate()
  .then(() => console.log('数据库连接成功...'))
  .catch(err => console.log('错误: ' + err));

// 中间件设置
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));

// 路由设置
app.use('/upload', uploadRoute);

// 静态文件服务
app.use('/uploads', express.static(path.join(__dirname, 'uploads')));

app.listen(PORT, () => {
  console.log(`服务器正在运行在 http://localhost:${PORT}`);
});

backend/models/db.js

创建一个用于连接MySQL数据库的文件db.js

const { Sequelize } = require('sequelize');

// 使用Sequelize连接到MySQL数据库
const db = new Sequelize('myapp', 'username', 'password', {
  host: 'localhost',
  dialect: 'mysql',
});

module.exports = db;

 backend/models/fileModel.js

定义文件模型fileModel.js,用于存储文件信息:

const { Sequelize, DataTypes } = require('sequelize');
const db = require('./db');

// 定义文件模型,包含文件名、路径、MIME类型和大小
const File = db.define('File', {
  filename: {
    type: DataTypes.STRING,
    allowNull: false,
  },
  path: {
    type: DataTypes.STRING,
    allowNull: false,
  },
  mimetype: {
    type: DataTypes.STRING,
    allowNull: false,
  },
  size: {
    type: DataTypes.INTEGER,
    allowNull: false,
  },
});

// 同步模型到数据库
db.sync()
  .then(() => console.log('文件模型已同步...'))
  .catch(err => console.log('错误: ' + err));

module.exports = File;

backend/routes/upload.js

设置文件上传路由upload.js,并使用multer处理文件上传:

const express = require('express');
const multer = require('multer');
const File = require('../models/fileModel');
const path = require('path');

const router = express.Router();

// 配置multer存储设置
const storage = multer.diskStorage({
  destination: (req, file, cb) => {
    cb(null, 'uploads/');
  },
  filename: (req, file, cb) => {
    cb(null, Date.now() + path.extname(file.originalname));
  },
});

const upload = multer({ storage: storage });

// 文件上传路由
router.post('/', upload.single('file'), async (req, res) => {
  try {
    const { file } = req;
    const newFile = await File.create({
      filename: file.filename,
      path: file.path,
      mimetype: file.mimetype,
      size: file.size,
    });

    res.status(201).json(newFile);
  } catch (error) {
    res.status(500).json({ error: '文件上传失败' });
  }
});

module.exports = router;

前端实现

2. 创建FileUpload组件

src/components/FileUpload.vue

创建一个文件上传组件FileUpload.vue

<template>
  <div class="file-upload-container">
    <h2>文件上传</h2>
    <form @submit.prevent="handleFileUpload">
      <div class="form-group">
        <label for="file">选择文件:</label>
        <input type="file" id="file" @change="onFileChange" required />
      </div>
      <button type="submit">上传文件</button>
    </form>
    <div v-if="uploadStatus" class="status">{{ uploadStatus }}</div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      file: null, // 保存用户选择的文件
      uploadStatus: '', // 保存上传状态信息
    };
  },
  methods: {
    // 当文件选择改变时,保存选中的文件
    onFileChange(event) {
      this.file = event.target.files[0];
    },
    // 处理文件上传
    handleFileUpload() {
      if (!this.file) {
        this.uploadStatus = '请先选择文件';
        return;
      }

      const formData = new FormData();
      formData.append('file', this.file);

      fetch('http://localhost:5000/upload', {
        method: 'POST',
        body: formData,
      })
      .then(response => response.json())
      .then(data => {
        this.uploadStatus = '文件上传成功';
        console.log('文件上传成功:', data);
      })
      .catch(error => {
        this.uploadStatus = '文件上传失败';
        console.error('文件上传失败:', error);
      });
    },
  },
};
</script>

<style scoped>
.file-upload-container {
  width: 300px;
  margin: 0 auto;
  padding: 20px;
  border: 1px solid #ccc;
  border-radius: 4px;
  background: #f9f9f9;
}

.form-group {
  margin-bottom: 15px;
}

.form-group label {
  display: block;
  margin-bottom: 5px;
}

.form-group input {
  width: 100%;
  padding: 8px;
  box-sizing: border-box;
}

button {
  width: 100%;
  padding: 10px;
  background-color: #4CAF50;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}

button:hover {
  background-color: #45a049;
}

.status {
  margin-top: 15px;
  font-size: 14px;
  color: green;
}
</style>

3. 在App.vue中整合组件

src/App.vue

App.vue中整合FileUpload组件:

<template>
  <div id="app">
    <header>
      <h1>我的应用</h1>
      <nav>
        <ul>
          <li @click="showFileUpload">文件上传</li>
        </ul>
      </nav>
    </header>
    <main>
      <FileUpload v-if="currentView === 'FileUpload'" />
    </main>
  </div>
</template>

<script>
import FileUpload from './components/FileUpload.vue';

export default {
  components: {
    FileUpload,
  },
  data() {
    return {
      currentView: 'FileUpload', // 当前显示的视图
    };
  },
  methods: {
    // 显示文件上传视图
    showFileUpload() {
      this.currentView = 'FileUpload';
    },
  },
};
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}

header {
  background-color: #35495e;
  padding: 10px 0;
  color: white;
}

nav ul {
  list-style: none;
  padding: 0;
}

nav ul li {
  display: inline;
  margin: 0 10px;
  cursor: pointer;
}
</style>

4. 启动应用

src/main.js

main.js中启动应用:

import Vue from 'vue';
import App from './App.vue';

Vue.config.productionTip = false;

new Vue({
  render: (h) => h(App),
}).$mount('#app');

5. 创建index.html

public/index.html

创建index.html文件,用于引导我们的Vue应用:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>文件上传应用</title>
</head>
<body>
  <div id="app"></div>
  <script src="/dist/build.js"></script>
</body>
</html>

 

结论

        在本文中,我们已经成功创建了一个可以上传文件并将文件信息存储到本地MySQL数据库的应用。我们使用了Vue.js作为前端框架,Node.js和Express作为后端框架,并使用MySQL作为数据库。希望这篇文章对你有所帮助,并且你可以根据自己的需求进行扩展和修改。

请记得一键三连(点赞、收藏、分享)哦!

  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

学不完了是吧

v我5块会的全告诉你

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值