React实现大文件上传、react-dropzone

2023-11-05

React大文件上传的实现方案大致如下:

  1. 使用第三方组件库实现文件上传,如react-dropzone。

  2. 将大文件分成多个小块,并使用XMLHttpRequest或者fetch发送分块上传请求。为了保证数据完整性,每个请求都需要携带校验码。在上传过程中需要实时统计上传进度。

  3. 后端接收到分块上传的请求后,将每个分块存储到指定路径下,并根据校验码判断分块是否完整。

  4. 当所有分块上传成功后,后端将分块整合成一个完整的文件,并删除已上传的分块。

  5. 当文件上传成功后,前端清除上传状态并显示成功的提示信息。

下面是一个基于react-dropzoneaxios实现的React大文件上传组件代码:

import React, { useState } from 'react';
import { useDropzone } from 'react-dropzone';
import axios from 'axios';

const LargeFileUploader = () => {
  const [uploadedFiles, setUploadedFiles] = useState([]);

  const onDrop = async (acceptedFiles) => {
    // 使用FormData来封装文件数据
    const formData = new FormData();
    acceptedFiles.forEach((file) => {
      formData.append('files', file);
    });

    try {
      // 发起上传请求
      const response = await axios.post('/upload-url', formData, {
        headers: { 'Content-Type': 'multipart/form-data' },
        onUploadProgress: (progressEvent) => {
          // 上传进度回调
          const progress = Math.round(
            (progressEvent.loaded / progressEvent.total) * 100
          );
          console.log(`Upload Progress: ${progress}%`);
        },
      });

      // 上传成功后更新已上传文件列表
      setUploadedFiles(response.data);
      console.log('Upload Successful!');
    } catch (error) {
      console.error('Upload Error:', error);
    }
  };

  const { getRootProps, getInputProps, isDragActive } = useDropzone({ onDrop });

  return (
    <div {...getRootProps()} className="dropzone">
      <input {...getInputProps()} />
      {isDragActive ? (
        <p>拖放文件到此处以上传</p>
      ) : (
        <p>将文件拖放至此处,或点击选择文件进行上传</p>
      )}
      <ul>
        {uploadedFiles.map((file, index) => (
          <li key={index}>{file.name}</li>
        ))}
      </ul>
    </div>
  );
};

export default LargeFileUploader;

        在上面的代码中,我们创建了一个名为LargeFileUploader的组件。它使用react-dropzone来实现文件拖放和选择功能,并使用axios发起上传请求。

        在onDrop方法中,我们首先将接收到的文件数据封装到FormData对象中,然后使用axios.post方法发送POST请求到指定的上传URL。我们设置请求头的Content-Typemultipart/form-data以支持文件上传。

        在请求配置中,我们还通过onUploadProgress参数传入一个回调函数,用于监视文件上传的进度并显示在控制台中。

        上传成功后,我们将服务器返回的已上传文件列表更新到uploadedFiles状态,并在页面中渲染出来。

        最后,在渲染部分,我们使用useDropzonehook获取所需的属性和事件绑定,并根据拖放状态显示相应提示信息和已上传文件列表。

        需要注意的是,示例中的上传URL路径/upload-url需要替换为自己的后端上传接口路径。另外,还需要对上传接口进行额外的处理和验证,以适应后端逻辑。

但是在文件比较大的情况下需要将文件切片上传,可以在使用react-dropzoneaxios的基础上进行扩展 ,在原有的基础上添加ChunkedFileUploader组件,并引入一个常量CHUNK_SIZE来指定切片大小(这里设置为1MB):

import React, { useState } from 'react';
import { useDropzone } from 'react-dropzone';
import axios from 'axios';

const CHUNK_SIZE = 1024 * 1024; // 切片大小为1MB

const ChunkedFileUploader = () => {
  const [uploadedChunks, setUploadedChunks] = useState({});
  const [uploadedFile, setUploadedFile] = useState(null);
  const [isUploading, setIsUploading] = useState(false);

  const onDrop = (acceptedFiles) => {
    const file = acceptedFiles[0];
    setUploadedFile(file);
  };

  const uploadChunks = async () => {
    if (!uploadedFile) return;

    setIsUploading(true);

    try {
      const totalChunks = Math.ceil(uploadedFile.size / CHUNK_SIZE);
      const chunksToUpload = [];

      // 分割文件为切片
      for (let i = 0; i < totalChunks; i++) {
        const start = i * CHUNK_SIZE;
        const end = Math.min(start + CHUNK_SIZE, uploadedFile.size);
        const chunk = uploadedFile.slice(start, end);
        chunksToUpload.push(chunk);
      }

      // 依次上传切片
      for (let i = 0; i < chunksToUpload.length; i++) {
        const formData = new FormData();
        formData.append('file', chunksToUpload[i]);
        formData.append('chunkNumber', i + 1);
        formData.append('totalChunks', totalChunks);

        await axios.post('/upload-url', formData, {
          headers: {
            'Content-Type': 'multipart/form-data',
          },
        });

        setUploadedChunks((prevChunks) => ({
          ...prevChunks,
          [i + 1]: true,
        }));
      }

      console.log('Upload Complete!');
    } catch (error) {
      console.error('Upload Error:', error);
    } finally {
      setIsUploading(false);
    }
  };

  const { getRootProps, getInputProps, isDragActive } = useDropzone({ onDrop });

  return (
    <div {...getRootProps()} className="dropzone">
      <input {...getInputProps()} />
      {isDragActive ? (
        <p>拖放文件到此处以上传</p>
      ) : (
        <p>将文件拖放至此处,或点击选择文件进行上传</p>
      )}
      {uploadedFile && !isUploading && (
        <button onClick={uploadChunks}>上传</button>
      )}
      {isUploading && <p>上传中...</p>}
      <ul>
        {Object.keys(uploadedChunks).map((chunkNumber) => (
          <li key={chunkNumber}>{`切片 ${chunkNumber}`}</li>
        ))}
      </ul>
    </div>
  );
};

export default ChunkedFileUploader;

        在上传时,根据文件大小计算出切片的总数。然后,我们通过循环将文件分割成多个切片,并使用FormData对象将每个切片进行封装。最后,通过循环依次上传每个切片,并在每个切片上传成功后更新已上传切片的状态。 

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

React实现大文件上传、react-dropzone 的相关文章

  • 如何实现 JavaScript 对象被垃圾回收时触发的函数?

    实际上 垃圾被收集 销毁或以其他方式超出范围 我想要做的是 当调用了 bind 方法的对象被销毁时 取消绑定非 DOM 元素上的事件处理程序 编辑 我又查看了我的代码 并决定我真正需要它的唯一地方是当不再需要包含该对象的模块时 这通常发生在
  • 需要帮助从数组中为国家/地区着色,保留其余默认颜色

    我需要一些帮助从我创建的数组中获取数据 然后仅对数组中存在的国家 地区进行着色 而不在数组中的其余国家 地区我希望保留为默认颜色 我正在使用 D3 来完成所有这些工作 并且我非常确定我可以通过 D3 实现我需要的目标 但不确定如何实现 我想
  • ReactTable 修复了最后一行

    我正在使用 ReactTable 最后我需要创建一些摘要 当分页存在时 它每次都应该可见 可以用react table来实现吗 我可以通过创建下一个表来部分解决这个问题 但我没有找到如何隐藏标题的方法 另一个问题是调整列宽度时 它不会应用于
  • Firebase Function 从其他文件导入函数 - javascript

    我正在使用 javascript 构建 firebase 函数 现在我有很多内部调用函数 我计划将这些函数移动到不同的文件中 以避免 index js 变得非常混乱 下面是当前的文件结构 functions index js interna
  • Javascript:混合构造函数模式和揭示模块模式

    有什么方法可以让 Javascript 类扩展通过揭示模块模式创建的对象吗 我尝试了下面的代码 但是有没有办法实现同样的事情 sv MergeQuestionViewModel function this sv QuestionDetail
  • 如何修复网站 iframe 错误?

    当我访问此网址时 警告 推荐使用一些广告拦截器 网页链接加载良好 没有错误 但是 当我尝试通过加载同一页面时iframe在我的html代码中 出现错误 我的html代码
  • React 不响应按键事件

    我正在尝试实现一些非常基本的按键检测 但我根本无法让它工作 我有一个裸露的组件 应该在onKeyDown事件 但控制台中没有任何内容被注销 class App extends React Component constructor prop
  • Access-Control-Allow-Headers 不允许请求标头字段 Access-Control-Allow-Headers

    我试图通过发布请求将文件发送到我的服务器 但是当它发送时会导致错误 Access Control Allow Headers 不允许请求标头字段 Content Type 所以我用谷歌搜索了错误并添加了标题 http post rootSc
  • 如何在 JS Rails 响应中包含 HTML?

    我有一个响应 HTML 和 JS AJAX 查询的 FooController app controllers foo controller rb class FooController lt ApplicationController l
  • 根据用户区域设置过滤字符串列表

    当使用 AngularJS 1 6 处理 JavaScript 项目时 我有一个要过滤的字符串列表 例如 假设我的列表包含 rbol cig e a nido and tubo 当过滤西班牙语字符串时 如果我过滤 u 我会期望两者cig e
  • less.js - 在解析器回调中获取变量值

    我正在使用 less js 1 3 0 在客户端将 less 解析为 css 在解析器的回调中 我想获取每个变量的值 我尝试了以下方法但没有成功 var data colour red example background color co
  • 使用 javascript 将 html 文本渲染为位图,无需服务器端代码

    我需要使用 javascript 代码来转换 html 中的文章 帖子 以便最终用户以位图的形式查看 有没有办法在没有服务器端代码的情况下做到这一点 example p testing text here p 您可以使用例如html2can
  • 使用 javascript 禁用按钮:FF 与 IE

    我有一排按钮 它们都会创建一个我想在新选项卡中打开的 pdf 文件 这样按钮页面就会保持在顶部 并且 pdf 会打开以进行打印 为了防止单击按钮两次 我禁用该按钮 如下所示 我使用 python
  • 默认情况下嵌入带字幕的 Youtube 不起作用

    我正在尝试嵌入 Youtube 电影 并希望默认情况下打开字幕 From https developers google com youtube player parameters cc load policy https develope
  • mouseover 和 mouseout 事件在子进程上触发

    代码 div div div div 如果我将鼠标悬停在Navigation the Drop Downdiv 向下滑动 如果我将鼠标移开 它会向上滑动 问题是如果我将鼠标悬停在孩子上Drop Downdiv它也向上滑 动 有谁知道我该如何
  • 如果多个键是相同的 JS,则对对象中的值求和

    例如我有 5 个对象 row aa col 1 value 1 row bb col 2 value 1 row bb col 3 value 1 row aa col 1 value 1 row aa col 2 value 1 我想对值
  • Javascript 中的线性回归 [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我想在网络浏览器中用 Javascript 进行最小二乘拟合 目前 用户使用 HTML 文本输入输入数
  • 如何检查 Map 或 Set 是否为空?

    对于 JavaScript 中的传统对象 使用以下命令很容易检查它是否为空 Object keys method const emptyObj console log Object keys emptyObj length 0 true i
  • 通过多个回调优雅地传递“点击事件”

    当未登录的用户单击给定的按钮时 我想停止该事件 收集他的 oauth 收集他的电子邮件 如果我没有 然后执行该事件 我想用 javascript 来做所有事情 因为这会让事情变得更加简单 这就是我执行它的方式 我有两个问题 有没有更优雅的方
  • 利用重力效果拖动元素

    我想完成类似于 photoshop com 和此网站的功能 http mrdoob com projects chromeexperiments google gravity http mrdoob com projects chromee

随机推荐

  • K-means聚类算法的三种改进(K-means++,ISODATA,Kernel K-means)介绍与对比

    原文 http www cnblogs com yixuan xu p 6272208 html K means聚类算法的三种改进 K means ISODATA Kernel K means 介绍与对比 一 概述 在本篇文章中将对四种聚类
  • 独立服务器的优点

    独立服务器有哪些优势 独立服务器的优势 1 稳定性好 一个人独享 拥有专业技术人员维护 2 独立服务器支持自动更新系统 自主设置安全策略以及系统环境是独立的 因此更加安全可靠 2 独立服务器操作系统中的http ftp ssh都是独立的 供
  • 判断两个List<Map>是否相同以及其他类操作

    根据自身的业务 搞了个list 是否相等的方法 较笨拙 有更好的方法 欢迎各位大佬指教 仅根据自身业务编写 如需改动请自便 改动也好改动 注释很详细 import com google common collect Maps import
  • [非线性控制理论]1_Lyapunov直接方法

    非线性控制理论 1 Lyapunov直接方法 非线性控制理论 2 不变性原理 非线性控制理论 3 基础反馈稳定控制器设计 非线性控制理论 4 反馈线性化 反步法 非线性控制理论 5 自适应控制器 Adaptive controller 非线
  • 【Python】Python可变参数*args **kwargs

    可变参数 args 和 kwargs 作为函数定义时 收集未匹配参数组成tuple或dict对象 参数也就是 args收集所有未匹配的位置参数组成一个tuple对象 局部变量args指向此tuple对象 参数也就是 kwargs收集所有未匹
  • 巧用异频测量快速评估友商4G网络覆盖

    摘 要 通过在联通4G网络异频测量配置数据中增加友商使用的4G网络频点 让联通现网中使用全网通的用户上报的测量报告数据 MR 包含有友商频点的测量信息 再对测量报告数据 MR 进行统计分析 可以实现快速 高效的对友商4G网络的覆盖进行全面评
  • 电流检测总结

    电流检测总结 电流检测是工业上常用到的一门技术 平常工作也经常与之打交道 因为我是小白 所以今天打算对它做一个简单的总结 防止遗忘 对于被检测的电路 一般使用阻值很小的采样电阻串联在电路中进行采样 然后检测这个采样电阻两端的电压信号 Vin
  • Unity Shader 实现描边OutLine效果

    Shader实现描边流程大致为 对模型进行2遍 2个pass 绘制 第一遍 描边pass 在vertex shader中对模型沿顶点法线方向放大 fragment shader设置输出颜色为描边颜色 第二遍正常绘制模型 除被放大的部分外 其
  • react如何调用子组件身上的方法

    使用场景 需要重复触发子组件弹窗或者需要在子组件修改值的时候可以采用调用子组件身上特定方法执行操作 在次介绍一下最新hooks的操作和旧版本class组件调用方式 一 Hooks api调用方式 需要用到的Api useRef useImp
  • 哈呀嗓,济南

    今天收到了泰莱区宏图三胞招聘主管的邮件 说是让联系沈经理 备注在这里以免忘记 还有就是 下午打印简历的时候潍坊新北海打电话过来 说他们公司也需要php程序员 这个也待定吧 一切还是以济南为主吧 不行再走 地形 济南市位于北纬36 40 东经
  • XXL-JOB(分布式任务调度平台)的使用(详细教程)

    概述 首先我们要知道什么是XXL JOB 官方简介 XXL JOB是一个分布式任务调度平台 其核心设计目标是开发迅速 学习简单 轻量级 易扩展 现已开放源代码并接入多家公司线上产品线 开箱即用 XXL JOB的有点特性 1 简单 支持通过W
  • Hibernate 项目查询数据报 UnknownEntityTypeException

    原因分析 1 hibernate cfg xml配置文件有没有映射实体类
  • 一文带你全面理解向量数据库

    近些年来 向量数据库引起业界的广泛关注 一个相关事实是许多向量数据库初创公司在短期内就筹集到数百万美元的资金 你很可能已经听说过向量数据库 但也许直到现在才真正关心向量数据库 至少 我想这就是你现在阅读本文的原因 如果你阅读本文只是为了简单
  • wireshark过滤器的使用

    目录 wireshark wireshark的基本使用 wireshark过滤器的区别 抓包案例 wireshark wireshark的基本使用 抓包采用 wireshark 提取特征时 要对 session 进行过滤 找到关键的stre
  • 华为云使用手册

    华为云重磅福利 云主机 海外云主机 云容器和多款云产品0元领取 华为云重磅推出云上优选 特惠来袭来迎接这个来之不易的春天 本次活动依然是给到了很低的折扣 0 7折起 活动走起 福利1 免费试用海外云主机和云原生容器网页连接 进入免费试用专区
  • CentOS安装python3.x最新版和chrome chromedriver

    之前使用selenium wire的响应拦截器获取请求头中的签名需要部署到服务器 所以得搭建一个服务器运行环境 安装过程有坑 这里记录一下 Linux平台安装需要下载源码包自己编译 下载地址 https www python org dow
  • hexo主题标签的使用

    https akilar top posts 615e2dec 这个是我看的教程 我直接复制的源码 友情链接 LrcShare 实现hexo标签的可以折叠 hexo标签的使用方法 要实现Hexo标签的可折叠 可以使用Hexo内置的foldi
  • ad中按钮开关的符号_收藏:电路图符号大全

    电子设备中有各种各样的图 能够说明它们工作原理的是电原理图 简称电路图 电路图是说明模拟电子电路工作原理的 它用各种图形符号表示电阻器 电容器 开关 晶体管等实物 用线条把元器件和单元电路按工作原理的关系连接起来 一张电路图就好像是一篇文章
  • 在SpringBoot中加入jsp

    SpringBoot官方不推荐在 SpringBoot 中使用 jsp 的 那么到底可以使用吗 答案是肯定的 不过需要导入tomcat 插件启动项目 不能再用 SpringBoot 默认 tomcat 了 一 导入SpringBoot的to
  • React实现大文件上传、react-dropzone

    React大文件上传的实现方案大致如下 使用第三方组件库实现文件上传 如react dropzone 将大文件分成多个小块 并使用XMLHttpRequest或者fetch发送分块上传请求 为了保证数据完整性 每个请求都需要携带校验码 在上