当前位置: 首页 > article >正文

前端大文件上传webuploader(react + umi)

使用WebUploader还可以批量上传文件、支持缩略图等等众多参数选项可设置,以及多个事件方法可调用,你可以随心所欲的定制你要的上传组件。

分片上传

1.什么是分片上传
分片上传,就是将所要上传的文件,按照一定的大小,将整个文件分隔成多个数据块(我们称之为Part)来进行分别上传,上传完之后再由服务端对所有上传的文件进行汇总整合成原始的文件。

2.分片上传的场景

1.大文件上传

2.网络环境环境不好,存在需要重传风险的场景

断点续传

1、什么是断点续传
断点续传是在下载或上传时,将下载或上传任务(一个文件或一个压缩包)人为的划分为几个部分,每一个部分采用一个线程进行上传或下载,如果碰到网络故障,可以从已经上传或下载的部分开始继续上传或者下载未完成的部分,而没有必要从头开始上传或者下载。本文的断点续传主要是针对断点上传场景。

2、应用场景
断点续传可以看成是分片上传的一个衍生,因此可以使用分片上传的场景,都可以使用断点续传。

具体使用

1.引入库

使用Web Uploader文件上传需要引入三种资源:JS, CSS, SWF。

先将webuploader.js , webuploader.css , jquery.min.js 放到静态资源public/scripts 文件中如:

在这里插入图片描述
由于我是react + Umi 的项目,在config.ts 文件中进行配置,所以导入方式:

links: [
    {
      href: './scripts/webuploader.css',
      rel: 'preload',
    },
  ],
  /**
   * @name <head> 中额外的 script
   * @description 配置 <head> 中额外的 script
   */
  headScripts: [
    // 解决首次加载时白屏的问题
    { src: '/scripts/loading.js', async: true },
    {
      src: '/scripts/jquery.min.js',
      charset: 'utf-8',
      type: 'text/javascript',
    },
    {
      src: '/scripts/webuploader.js',
      charset: 'utf-8',
      type: 'text/javascript',
    },
    // `https://sandcastle.cesium.com/Sandcastle-header.js`,
    `window.WebUploader = WebUploader`,
  ],
2.业务组件

index.ts

<div>
	<div id="upload-container">
    	<span>点击或者拖拽到此处上传</span>
	</div>
	<span id="picker" class="showclass">点击上传文件</span>
	{uploading && (
	  <>
	     {uploader.current.getFiles()?.[0].name}
	     <Progress percent={percent} />
	   </>
	 )}
</div>

3.初始化

从前端代码可以看出上传文件为一个span文本,Web Uploader将其初始化成为
一个可以上传文件的按钮

import { useRef, useEffect, useState } from "react";
import {
  Progress,
} from "antd";
const Index = () => {
  const uploader = useRef(null as any);
  const [percent, setPercent] = useState(0);
  const [errRes, setErrRes] = useState({} as any);
  const [uploading, setUploading] = useState(false);
  useEffect(() => {
    $('#upload-container').click(function(event) {
     	$("#picker").find('input').click();
  	});
  	// 取消上传
	$('.upload-list').on('click', '.btn-remove', function(){
   		// 从文件队列中删除某个文件id
   		file_id = $(this).data('id');
   		uploader.current.removeFile(file_id, true); // 从队列中删除
	    // console.log(uploader.getFiles()) // 队列显示还在  其实已经删除
	});
	// 重新上传
	$('.upload-list').on('click', '.upload-item__progress span', function(){
	    uploader.current.retry($(this).data('file'));
	});
	// 刷新容器(解决文件上传按钮失效问题)
    $("#picker").hide();
    $('#forecastSelect4').change(function(){
        $("#picker").show();
        uploader.refresh();//刷新容器 解决隐藏后失效问题
    });
    initUploader();
  });

  const initUploader = () => {
    const { WebUploader } = window as any;
    uploader.current = WebUploader.create({
      auto: false, // 选完文件后,是否自动上传。
      //duplicate:true, // 可重复上传
      swf: "/Uploader.swf", // swf文件路径
      server: "/api/data/xxx", // 文件接收服务端。
      pick: {
        id: "#picker",
        label: "Select Data File",
        multiple: false,
      }, // 内部根据当前运行是创建,可能是input元素,也可能是flash. 这里是div的id
      // multiple: true, // 选择多个
      chunked: true, // 开起分片上传。
      threads: 5, // 上传并发数。允许同时最大上传进程数。
      method: "POST", // 文件上传方式,POST或者GET。
      // fileSizeLimit: 1024 * 1024 * 100 * 100, //验证文件总大小是否超出限制, 超出则不允许加入队列。
      // fileSingleSizeLimit: 1024 * 1024 * 100 * 100, //验证单个文件大小是否超出限制, 超出则不允许加入队列。
      formData: {},
      fileVal: "file", // [默认值:'file'] 设置文件上传域的name。
      accept: {
        title: "package",
        extensions: "tar.gz,tgz,tar,zip",
        mimeTypes: ".tar.gz,.tgz,.tar,.zip",
      },
      headers: {
        token: localStorage.getItem("token"),
      },
    });

    uploader.current.on(
      "uploadBeforeSend",
      async function ({ file }: any, data: any) {
        // data.md5 = file.md5; // md5 在父组件中提前一步注册
        if (data.hasOwnProperty("chunk")) {
          data.chunk = data.chunk + 1;
        } else {
          data.chunk = 1;
        }
      }
    );

    uploader.current.on("beforeFileQueued", async (file: any) => {
      uploader.current.reset();
    });

	// 1.添加文件到队列时
    uploader.current.on("fileQueued", async (file: any) => {
      form
        .validateFields()
        .then((values: any) => {
          createProjectRequest({
            project_name: values.project_name,
            sub_project_name: values.sub_project_name,
          }).then((res: any) => {
            setUploading(true);
            fileRef.current = file;
            subPid.current = res.sub_project_id;

            uploader.current.upload();
          });
        })
        .catch((err: any) => {
          uploader.current.reset();
        });
    });
	// 2.文件上传过程中添加进度显示
    uploader.current.on("uploadProgress", (file: any, p: number) => {
      const _p = Math.floor(p * 100);
      setPercent(_p > 99.99 ? 99.99 : _p);
    });
    
	// 3.文件上传成功或失败时触发
    uploader.current.on("uploadSuccess", (file: any, response: any) => {
      completeProjectData({
        name: file.name,
        size: file.size,
        sub_project_id: subPid.current,
      })
        .then((res) => {
          setPercent(100);
          message.success("导入成功");
        })
        .catch(() => {
          setPercent(100);
        });
    });
}

export default Index;

OK,收工!如果可以实现记得点赞分享,谢谢老铁~


http://www.kler.cn/a/162546.html

相关文章:

  • SQL集合运算
  • react 中 useContext Hook 作用
  • 【大数据学习 | HBASE高级】rowkey的设计,hbase的预分区和压缩
  • Python →爬虫实践
  • 每日一练:二分查找-搜索插入位置
  • FFmpeg 4.3 音视频-多路H265监控录放C++开发十三:将AVFrame转换成AVPacket。视频编码原理.编码相关api
  • QT作业2
  • Scala 从入门到精通
  • 【前端】没有了element时,怎么实现一个自己的form表单组件和表单校验(用法参考el-form)
  • 这些接口自动化测试工具如果不知道,就真out了!
  • unity 2d 入门 飞翔小鸟 小鸟跳跃 碰撞停止挥动翅膀动画(十)
  • 机器学习-分类问题
  • Tmux中使用Docker报错 - 解决方案
  • Windows下使用CMD修改本地IP
  • SQL自学通之简介
  • PyQt6 QTimeEdit时间控件
  • YOLOv5独家原创改进:SPPF自研创新 | SPPF与感知大内核卷积UniRepLK结合,大kernel+非膨胀卷积提升感受野
  • 7天用Go实现分布式缓存
  • 简谈MySQL的binlog模式
  • ALTERNET STUDIO 9.1 Crack
  • 啃下这50道笔试题,你就是SQL专家!(附答案,收藏备用)
  • 元宇宙vr党建云上实景展馆扩大党的影响力
  • 将 ONLYOFFICE 协作空间的公共房间嵌入到网页
  • 复杂sql分析 以及 索引合并
  • 使用异或查找数组中出现奇数次的唯一或唯二数字
  • Vue.directive