首页 > 其他分享 >大文件上传1(前端)

大文件上传1(前端)

时间:2024-09-26 09:51:42浏览次数:3  
标签:文件 const 前端 worker file new hash 上传

前言:

近期要做一个视频网站,但是管理平台需要上传音/视频,记录一下这种大文件上传的方法吧。

方案:断点续传(分片上传)

实现断点续传的逻辑

  • 在上传前检查文件的哈希值,判断哪些分片已经上传,避免重复上传
  • 在所有分片上传完成后,合并分片

技术栈: vue3 + element-plus + vite + web worker + spark-md5

// upload.vue
<template>
  <div>
    <el-upload class="upload-demo" drag action="#" :auto-upload="false" :limit="1" :on-change="uploadfile">
      <el-icon class="el-icon--upload"><upload-filled /></el-icon>
      <div class="el-upload__text">将文件拖放到此处或 <em>单击上传</em></div>
    </el-upload>
  </div>
</template>

<script setup lang="ts">
import { ref } from "vue";
import axios from "axios";
const chunks = ref([]);
const file = ref<any>();
const hash = ref("");
// 使用自定义上传
const uploadfile = async option => {
  file.value = option.raw;
  // 创建切片
  await createFileChunks();
  // 进行上传并合并
  handleUpload();
};
// 创建切片
const createFileChunks = async () => {
  return new Promise((resolve, reject) => {
    // 使用web worker, import.meta.url 为当前文件的路径
    const worker = new Worker(new URL("./fileWorker.js", import.meta.url), { type: "module" });
    console.log(worker, "work");
    worker.postMessage({ file: file.value });
    worker.onmessage = e => {
      chunks.value = e.data.chunks;
      hash.value = e.data.hash;
      resolve(true);
    };
    worker.onerror = e => {
      console.log(e, "worker error");
      reject(e);
    };
  });
};
// 上传并合并切片
const handleUpload = async () => {
  await uploadChunks();
  await axios.post("http://localhost:3000/fileUpload/merge", { hash: hash.value, fileName: file.value.name });
};
// 循环上传
const uploadChunks = async () => {
  const requests = chunks.value.map((chunk, index) => {
    const formData = new FormData();
    formData.append("chunk", chunk);
    formData.append("hash", `${hash.value}-${index}`);
    return axios.post("http://localhost:3000/fileUpload", formData);
  });
  await Promise.all(requests);
};
</script>

<style scoped></style>

fileWorker.js

import SparkMD5 from "spark-md5";
self.onmessage = async function (e) {
  const { file } = e.data;
  const chunks = [];
  const SIZE = 10 * 1024 * 1024; // 10MB
  let cur = 0;

  while (cur < file.size) {
    chunks.push(file.slice(cur, cur + SIZE));
    cur += SIZE;
  }
  try {
    const hash = await calculateHash(file);
    self.postMessage({ chunks, hash });
  } catch (error) {
    self.postMessage({ error: error.message });
  }
};

function calculateHash(file) {
  return new Promise(resolve => {
    const spark = new SparkMD5.ArrayBuffer();
    const fileReader = new FileReader();
    fileReader.onload = e => {
      spark.append(e.target.result);
      resolve(spark.end());
    };
    fileReader.onerror = () => {
      reject(new Error("读取文件时出错"));
    };

    fileReader.readAsArrayBuffer(file);
  });
}

这样就完成了。

为何使用web Worker ?

因为文件的MD5值计算是纯运算,将阻塞JS主线程的运行,在文件较大时,计算过程将使得浏览器长时间处于无响应状态而web-worker与JS处于不同的线程,相互并不阻塞,因此可以将一些耗时的纯运算放在web-worker中进行,等待完成后通知到JS主线程。

好了,以上是前端上传大文件的前端demo示例。

标签:文件,const,前端,worker,file,new,hash,上传
From: https://blog.csdn.net/qq_38133850/article/details/142546693

相关文章

  • 前端面试题(七)
    33.前端状态管理什么是状态管理?状态管理是指在应用程序中管理和维护不同组件之间共享的数据状态的过程。随着应用规模的扩大,状态管理变得愈发复杂,尤其是在单页应用(SPA)中。常见的状态管理库有哪些?Redux:一个流行的JavaScript状态管理库,基于单一状态树和不可变状态......
  • 前端面试题(八)
    39.现代前端框架当前流行的前端框架有哪些?React:由Facebook开发的一个用于构建用户界面的JavaScript库,采用组件化开发,支持虚拟DOM和单向数据流。主要特性:组件复用:将UI分割成独立的、可复用的组件。ReactHooks:允许在函数组件中使用状态和生命周期方法。......
  • 第一章:COMTRADE 四种文件类型概述
    第一章:COMTRADE四种文件类型概述推荐一款COMTRADE录波文件|可视化工具|电能质量查看软件官网地址:COMTRADEChart概述每个COMTRADE记录包括多达四个相关联的文件,这四个文件各自包含不同的信息,这四个文件是:头文件配置文件数据文件信息文件每一次记录的四个文件......
  • 第二章:COMTRADE 头文件
    第二章:COMTRADE头文件推荐一款COMTRADE录波文件|可视化工具|电能质量查看软件官网地址:COMTRADEChart概述头文件是ASCII文本文件,存储补充叙述性信息,帮助用户更好地理解暂态记录的条件。头文件不是应用程序必须处理的。内容可能包含的信息有:扰动前电力系统的描述;......
  • 第三章:COMTRADE 配置文件
    第三章:COMTRADE配置文件推荐一款COMTRADE录波文件|可视化工具|电能质量查看软件官网地址:COMTRADEChart概述配置文件是ASCI文本文件,提供给人或计算机程序阅读和解释相关数据文件中的数据值所必须的信息。配置文件具有预定的标准化格式,故无需为每个配置文件编写计算机......
  • 跨地域协作新篇章:异地传输文件的最优方案!
    基于市场拓展、获取丰富资源、实现长期战略目标、分散运营风险等考量,企业会在多个城市或国家设立分支机构,用以覆盖更广泛的市场和客户群体,提高业务的可靠性和稳定性。企业在实现总分支机构之间异地传输文件时,会面临以下挑战:1.管理难统一不同业务部门、机构之间进行文件传输交换,......
  • 智能同步,效率倍增:Ftrans文件自动化实时同步技术革新!
    随着企业结构分散化,企业内部数据流转更加频繁,为了保证数据在不同平台和设备之间的一致性和可用性、保障数据的安全性并有效支撑业务开展,越来越多的企业需要将内部数据在多个数据中心之间、多台服务器之间、多云和本地间进行服务器文件自动化实时同步处理。通过同步软件,企业能够更......
  • 【粉丝福利社】循序渐进Vue.js 3.x前端开发实践
    ......
  • 使用 Vue3、TypeScript 和 Spring Boot 实现文件上传至 MinIO 和 OSS
    目录《使用Vue3、TypeScript和SpringBoot实现文件上传至MinIO和OSS》一、技术选型二、环境搭建三、前端实现四、后端实现五、代码解析在现代web应用开发中,文件上传是一个常见的需求。本文将介绍如何使用Vue3、TypeScript和SpringBoot实现文件上传功能,并......
  • 如何获取文件路径
    文章目录1概念介绍2实现方法3示例代码我们在上一章回中介绍了"如何实现本地存储"相关的内容,本章回中将介绍如何实现文件存储.闲话休提,让我们一起TalkFlutter吧。1概念介绍我们在上一章回中介绍的本地存储只能存储dart语言中基本类型的数值,如果遇到大的......