React与Node.js实现文件上传进度条

作者:夜航船

时间:2026-10-26

浏览:579

本文介绍如何使用React和Node.js(Koa2)实现文件上传进度条功能。前端利用React状态管理与axios库跟踪上传进度,后端通过koa-body中间件处理文件存储与下载接口,提供完整的代码示例与启动步骤。

文章目录

正文

在现代Web应用中,文件上传是常见需求。上传进度条能实时反馈上传状态,帮助用户掌握进度并安排后续操作。本教程将演示如何结合React与Node.js完成该功能。

技术栈

  • React:用于构建用户界面的流行JavaScript库。
  • Node.js:基于JavaScript的跨平台轻量级运行时环境。
  • Koa2:基于Node.js的Web开发框架,提供简洁且强大的API。

实现过程

1. 前端

import React, { useState } from 'react';
import axios from 'axios';
function UploadForm() {
  const [selectedFile, setSelectedFile] = useState(null);
  const [uploadProgress, setUploadProgress] = useState(0);
  const [uploadedFile, setUploadedFile] = useState(null);
  const handleFileSelect = (event) => {
    setSelectedFile(event.target.files[0]);
  };
  const handleSubmit = async (event) => {
    event.preventDefault();
    const formData = new FormData();
    formData.append('file', selectedFile);
    const config = {
      onUploadProgress: (progressEvent) => {
        const percentCompleted = Math.round(
          (progressEvent.loaded * 100) / progressEvent.total
        );
        setUploadProgress(percentCompleted);
      },
    };
    try {
      const response = await axios.post('/api/upload', formData, config);
      setUploadedFile(response.data.filename);
      setSelectedFile(null);
      setUploadProgress(0);
    } catch (error) {
      console.log(error);
    }
  };
  const handleDownload = async () => {
    try {
      const response = await axios.get(`/api/download?filename=${uploadedFile}`, {
        responseType: 'blob',
      });
      const url = window.URL.createObjectURL(new Blob([response.data]));
      const link = document.createElement('a');
      link.href = url;
      link.setAttribute('download', uploadedFile);
      document.body.appendChild(link);
      link.click();
    } catch (error) {
      console.log(error);
    }
  };
  return (
    <div>
      <form onSubmit={handleSubmit}>
        <input type="file" onChange={handleFileSelect} />
        <button type="submit">Upload</button>
      </form>
      {selectedFile && (
        <div>
          Uploading {selectedFile.name}: {uploadProgress}%
        </div>
      )}
      {uploadedFile && (
        <div>
          File uploaded: <a href="#" rel="external nofollow"  onClick={handleDownload}>{uploadedFile}</a>
        </div>
      )}
    </div>
  );
}
export default UploadForm;

首先定义UploadForm组件,包含表单及若干状态变量。用户选择文件后,将其保存至状态中;提交表单时,利用axios库将文件上传至服务器,并通过状态变量监控上传进度。若上传成功,则保存文件名并将状态重置为初始值。

文件上传成功后,页面将显示下载链接。用户点击该链接时,使用axios库从服务器下载文件,并保存至本地计算机。

2. 后端服务(server.js)

const Koa = require("koa");
const Router = require("koa-router");
const koaBody = require("koa-body");
const cors = require("@koa/cors");
const fs = require("fs");
const path = require("path");
const app = new Koa();
const router = new Router();
// 配置跨域
app.use(cors());
// 配置Koa Body中间件以处理文件上传
app.use(
  koaBody({
    multipart: true,
    formidable: {
      uploadDir: path.join(__dirname, "uploads"),
      keepExtensions: true,
    },
  })
);
// 上传接口
router.post("/api/upload", async (ctx) => {
  const file = ctx.request.files.file;
  const filename = file.name;
  const filepath = file.path || file.filepath;
  // 计算文件大小
  const fileSizeInBytes = fs.statSync(filepath).size;
  const fileSizeInMegabytes = fileSizeInBytes / (1024 * 1024);
  ctx.body = {
    filename,
    size: fileSizeInMegabytes.toFixed(2),
  };
});
// 下载接口
router.get("/api/download", async (ctx) => {
  const filename = ctx.query.filename;
  const filepath = path.join(__dirname, "uploads", filename);
  const fileStream = fs.createReadStream(filepath);
  ctx.response.attachment(filename);
  ctx.body = fileStream;
});
app.use(router.routes());
app.use(router.allowedMethods());
// 启动!
const port = process.env.PORT || 3001;
app.listen(port, () => {
  console.log(`Server started on port ${port}`);
});

首先引入所需模块,创建Koa实例并连接路由器。启用CORS以允许跨域访问API。

使用koa-body中间件处理文件上传。该中间件将文件存储于本地文件系统,并将文件元数据附加至请求对象。

定义两个路由处理程序:一个用于处理文件上传,另一个用于处理文件下载。在上传处理程序中,从请求对象获取文件,并将文件名和大小返回给客户端;在下载处理程序中,读取文件并返回给客户端。

最后将路由器连接至Koa应用实例,并在端口3001上启动服务器。

应用程序开发已完成。可使用以下命令启动服务器和客户端:

// 前端
npm run start
//服务端
node server.js

以上即为使用React和Node.js实现文件上传进度条功能的全过程。

以上是React和Node.js快速上传进度条功能实现的详细内容,更多关于React Node.js上传进度条的资料请关注本站其它相关文章!

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章