返回

轻轻松松玩转React + Koa 文件断点续传,原来这么简单!

前端

断点续传是一项必备技术,它允许用户在因网络中断或其他意外情况导致文件传输中断时,能够从中断点继续传输文件,而无需从头开始。在本文中,我们将介绍如何使用React + Koa来实现文件断点续传。

先来了解一下什么是断点续传

断点续传是一种允许用户在因网络中断或其他意外情况导致文件传输中断时,能够从中断点继续传输文件,而无需从头开始的技术。这在文件传输中非常有用,因为它可以节省时间和带宽。

React + Koa实现断点续传

1. 安装依赖

npm install --save koa multer busboy md5-file

2. 配置Koa

const Koa = require('koa');
const app = new Koa();
app.use(bodyParser.json());
app.use(multer().single('file')); // 文件上传中间件

app.post('/upload', async (ctx, next) => {
  // 获取文件信息
  const file = ctx.req.file;
  // 获取文件大小
  const size = file.size;
  // 获取文件名称
  const name = file.originalname;

  // 检查文件是否存在
  const md5 = require('md5-file').sync(file.path);
  const existFile = await File.findOne({ md5 });
  if (existFile) {
    ctx.body = {
      code: 0,
      message: '文件已存在',
      data: {
        url: existFile.url,
      },
    };
    return;
  }

  // 文件不存在,开始上传
  const stream = fs.createReadStream(file.path);
  const chunks = [];
  stream.on('data', (chunk) => {
    chunks.push(chunk);
  });
  stream.on('end', async () => {
    const buffer = Buffer.concat(chunks);
    const md5 = crypto.createHash('md5').update(buffer).digest('hex');
    const fileData = {
      name,
      size,
      md5,
      data: buffer,
    };
    const newFile = new File(fileData);
    await newFile.save();
    ctx.body = {
      code: 0,
      message: '文件上传成功',
      data: {
        url: newFile.url,
      },
    };
  });
});

app.get('/download/:id', async (ctx, next) => {
  // 获取文件ID
  const id = ctx.params.id;
  // 查找文件
  const file = await File.findById(id);
  if (!file) {
    ctx.body = {
      code: 404,
      message: '文件不存在',
    };
    return;
  }

  // 文件存在,开始下载
  ctx.set('Content-Disposition', `attachment; filename=${file.name}`);
  ctx.set('Content-Type', 'application/octet-stream');
  ctx.body = file.data;
});

app.listen(3000);

3. 使用React前端

import React, { useState } from 'react';
import axios from 'axios';

const App = () => {
  const [file, setFile] = useState(null);
  const [progress, setProgress] = useState(0);

  const handleChange = (e) => {
    setFile(e.target.files[0]);
  };

  const handleSubmit = (e) => {
    e.preventDefault();

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

    axios.post('/upload', formData, {
      onUploadProgress: (event) => {
        setProgress(Math.round((event.loaded / event.total) * 100));
      },
    })
    .then((res) => {
      console.log(res.data);
    })
    .catch((err) => {
      console.log(err);
    });
  };

  return (
    <div>
      <form onSubmit={handleSubmit}>
        <input type="file" onChange={handleChange} />
        <button type="submit">上传</button>
      </form>
      <div>{progress}%</div>
    </div>
  );
};

export default App;

结语

本文介绍了如何使用React + Koa来实现文件断点续传。通过这种方法,我们可以轻松实现文件的大文件上传和下载,而且速度非常快。希望本文对您有所帮助。