vue node 实现文件的分片上传

以下是一个简单的示例代码,演示了如何使用Node.js的Koa2框架结合Vue3实现文件的分片上传:

在服务器端(Node.js + Koa2):

```javascript
const Koa = require('koa');
const Router = require('koa-router');
const bodyParser = require('koa-bodyparser');
const fs = require('fs');

const app = new Koa();
const router = new Router();

// 设置中间件
app.use(bodyParser());

// 处理文件分片上传
router.post('/upload', async (ctx) => {
  const { filename, index, total, data } = ctx.request.body;

  const uploadPath = `./uploads/${filename}`;
  const writeStream = fs.createWriteStream(uploadPath, { flags: 'a' });

  // 将分片数据追加写入文件
  writeStream.write(Buffer.from(data, 'base64'));

  // 如果是最后一个分片,则关闭写入流,表示上传完成
  if (index === total - 1) {
    writeStream.end();

    ctx.body = {
      message: 'Upload complete',
      file: uploadPath,
    };
  } else {
    ctx.body = {
      message: 'Upload in progress',
    };
  }
});

app.use(router.routes()).use(router.allowedMethods());

app.listen(3000, () => {
  console.log('Server is running on http://localhost:3000');
});

在客户端(Vue3):

<template>
  <div>
    <input type="file" @change="handleFileChange" />
    <button @click="startUpload">Start Upload</button>
    <p>{{ message }}</p>
    <p>{{ progress }}</p>
  </div>
</template>

<script>
export default {
  data() {
    return {
      file: null,
      message: '',
      progress: 0,
    };
  },
  methods: {
    handleFileChange(event) {
      this.file = event.target.files[0];
    },
    async startUpload() {
      const CHUNK_SIZE = 1024 * 1024; // 分片大小

      const totalChunks = Math.ceil(this.file.size / CHUNK_SIZE);
      let currentChunk = 0;

      while (currentChunk < totalChunks) {
        const start = currentChunk * CHUNK_SIZE;
        const end = Math.min(this.file.size, start + CHUNK_SIZE);

        const chunk = this.file.slice(start, end);
        const chunkReader = new FileReader();

        chunkReader.readAsDataURL(chunk);

        await new Promise((resolve) => {
          chunkReader.onload = async (event) => {
            const data = event.target.result;

            const response = await fetch('http://localhost:3000/upload', {
              method: 'POST',
              headers: {
                'Content-Type': 'application/json',
              },
              body: JSON.stringify({
                filename: this.file.name,
                index: currentChunk,
                total: totalChunks,
                data: data.split(',')[1], // 去除base64前缀
              }),
            });

            const result = await response.json();

            if (result.message === 'Upload in progress') {
              this.message = 'Uploading...';
              this.progress = Math.round(((currentChunk + 1) / totalChunks) * 100);
              currentChunk++;
              resolve();
            } else if (result.message === 'Upload complete') {
              this.message = 'Upload complete';
              this.progress = 100;
              resolve();
            }
          };
        });
      }
    },
  },
};
</script>

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

lionliu0519

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值