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

怎么盗号网站怎么做百度推广总部电话

怎么盗号网站怎么做,百度推广总部电话,网站书店建设背景,做今日头条的怎么去网站找视频大文件分片上传 内容 一般情况下,前端上传文件就是new FormData,然后把文件 append 进去,然后post发送给后端就完事了,但是文件越大,上传的文件也就越长,如果在上传过程中,突然网络故障,又或者…

大文件分片上传

内容

一般情况下,前端上传文件就是new FormData,然后把文件 append 进去,然后post发送给后端就完事了,但是文件越大,上传的文件也就越长,如果在上传过程中,突然网络故障,又或者请求超时,等待过久等等情况,就会导致错误而后又得重新传大文件。所以这时候就要使用分片上传了,就算断网了也能继续接着上传(断点上传),如果是之前上传过这个文件了(服务器还存着),就不需要做二次上传了(秒传)。

7.17实现方式

首先获取文件信息后设定分片大小对文件进行分片(slice函数),而后为文件生成一个hash对文件进行标注。在请求时先验证所上传的文件是否已经存在于服务器(若是则直接提示上传成功,即秒传功能),若不存在或部分存在则需要后端返回上传成功的分片标识数组,前端将使用成功分片数组与原文件分片数组进行处理得到未上传成功的分片,而后将未成功的分片以并发方式上传至后端。上传后即完成了整个文件的上传,向后端发送合并分片请求即完成大文件分片上传,断点续传功能。

7.19实现方式(即彻底完成功能)

步骤:

  1. 由于前端计算md5耗时过长,可能会导致页面卡死,因此考虑使用Web Worker来计算md5,即使用worker.js(使用spark-md5)文件来计算:分片数组,分片哈希数组,文件整体哈希。
  2. 在拿到web worker所得到的分片数组,分片哈希数组,文件整体哈希后,即可开始进行大文件上传工作,前端使用文件整体哈希、文件名以及分片数组作为请求参数调用后端/init接口初始化上传操作。【initSend函数】。
  3. 初始化操作完成后,前端使用文件整体哈希作为参数调用后端/status接口获取此文件分片的状态信息,前端根据后端所返回的状态信息使用filter以及every方法得到:文件是否已经上传的状态existFile、后端存在的文件分片existChunks。若existFile为true,则直接提示上传成功,即秒传功能。【verifyInfo函数】
  4. 若existFile为false,则使用后端返回的existChunks数组与分片数组进行对比,得到未上传成功的分片数组,并将其分片信息(分片哈希值,分片内容,分片序号以及文件整体哈希值)作为formData参数发送至后端/chunk接口(在发送分片时使用并发操作,并限制最大并发数为6)【uploadChunks函数】
  5. 当所有分片发送完成后,前端给后端以文件整体哈希做为参数调用后端/merge接口提示后端可以进行合并操作,后端返回成功消息即完成大文件分片上传,断点续传功能。【mergeFile函数】

演示图

  1. 选择文件:
    在这里插入图片描述

  2. 秒传:
    在这里插入图片描述

  3. 分片上传:
    在这里插入图片描述


代码内容

在后续操作中,完成了对请求的封装以及分片上传的hook的编写,主处理逻辑部分仅仅为下方所示:

const submitUpload = () => {const file = FileInfo.value;if(!file) {return;}fileName.value = file.name;const { mainDeal } = useUpload(file, fileName.value)mainDeal()
}

api的封装为下方所示:

import request from "@/utils/request";export async function initSend(uploadId, fileName, totalChunk) {return request({url: "/init",method: "POST",data: {uploadId,fileName,totalChunk,},});
}export async function verifyInfo(uploadId) {return request({url: "/status",method: "POST",data: {uploadId,},headers: { "Content-Type": "application/x-www-form-urlencoded" },});
}
export async function uploadSingle(formData) {return request({url: "/chunk",method: "POST",data: {formData,},headers: {"Content-Type": "multipart/form-data",},});
}
export async function mergeFile(uploadId) {return request({url: "/merge",method: "POST",data: {uploadId,},headers: {"Content-Type": "application/x-www-form-urlencoded",},});
}

useUpload钩子函数为:

import { ref } from "vue";
import axios from "axios";
import type { AxiosResponse } from "axios";
import {initSend,verifyInfo,mergeFile,uploadSingle,
} from "@/apis/uploadApi";
export function useUpload(fileInfo, filename) {const FileInfo = ref<File>(fileInfo);const fileName = ref(filename); // 文件名称const fileHash = ref(""); // 文件hashconst fileHashArr = ref([]);const chunks = ref([]);interface Verify {id?: Number;uploadId?: String;chunkIndex?: Number;status?: String;}const mainDeal = async () => {const worker = new Worker(new URL("@/utils/worker.js", import.meta.url), {type: "module",});const file = FileInfo.value;console.log(worker);console.log("file_info", file);worker.postMessage({ file: file });worker.onmessage = async (e) => {const { data } = e;chunks.value = data.fileChunkList;fileHashArr.value = data.fileChunkHashList;fileHash.value = data.fileMd5;console.log("uploadid", fileHash.value);const res_init = await initSend(fileHash.value,fileName.value,chunks.value.length);console.log("res_init", res_init);const { existFile, existChunks } = await verify(fileHash.value);if (existFile) return;uploadChunks(chunks.value, existChunks, fileHashArr.value);worker.terminate();};};// 控制请求并发const concurRequest = (taskPool: Array<() => Promise<Response>>,max: number): Promise<Array<Response | unknown>> => {return new Promise((resolve) => {if (taskPool.length === 0) {resolve([]);return;}console.log("taskPool", taskPool);const results: Array<Response | unknown> = [];let index = 0;let count = 0;console.log("results_before", results);const request = async () => {if (index === taskPool.length) return;const i = index;const task = taskPool[index];index++;try {results[i] = await task();console.log("results_try", results);} catch (err) {results[i] = err;} finally {count++;if (count === taskPool.length) {resolve(results);}request();}};const times = Math.min(max, taskPool.length);for (let i = 0; i < times; i++) {request();}});};// 合并分片请求const mergeRequest = async () => {return mergeFile(fileHash.value);};// 上传文件分片const uploadChunks = async (chunks: Array<Blob>,existChunks: Array<string>,md5Arr: Array<string>) => {const formDatas = chunks.map((chunk, index) => ({fileHash: fileHash.value,chunkHash: fileHash.value + "-" + index,chunkIndex: index,checksum: md5Arr[index],chunk,})).filter((item) => !existChunks.includes(item.chunkHash));console.log("formDatas", formDatas);const form_Datas = formDatas.map((item) => {console.log("!", item.chunkIndex);const formData = new FormData();formData.append("uploadId", item.fileHash);formData.append("chunkIndex", String(item.chunkIndex));formData.append("checksum", item.checksum);formData.append("file", item.chunk);return formData;});console.log("formDatas", form_Datas);const taskPool = form_Datas.map((formData) => () =>fetch("http://10.184.131.57:8101/ferret/upload/chunk", {method: "POST",body: formData,}));//控制请求并发const response = await concurRequest(taskPool, 6);console.log("response", response);// 合并分片请求const res_merge = await mergeRequest();console.log("res_merge", res_merge);};// 校验文件、文件分片是否存在const verify = async (uploadId: string) => {const res = await verifyInfo(uploadId);const { data } = res.data;console.log("verify", res);// 看服务器是不是已经有文件所有信息const existFile = data.every((item: Verify) => item.status === "Uploaded");const existChunks: string[] = [];data.filter((item: Verify) => {if (item.status === "Uploaded") {existChunks.push(`${item.uploadId}-${item.chunkIndex}`);}});console.log("existFile", existFile, "existChunks", existChunks);return {existFile,existChunks,};};return {mainDeal,};
}

web worker实现方式:

import SparkMD5 from 'spark-md5';
let DefaultChunkSize = 1024 * 1024 * 5; // 5MBself.onmessage = (e) => {console.log("!!>", e.data)if (e.data.file.size >= 1024 * 1024 * 100 && e.data.file.size < 1024 * 1024 * 512) {DefaultChunkSize = 1024 * 1024 * 10}else if (e.data.file.size >= 1024 * 1024 * 512) {DefaultChunkSize = 1024 * 1024 * 50}const { file, chunkSize = DefaultChunkSize } = e.data;let blobSlice = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice,chunks = Math.ceil(file.size / chunkSize),currentChunk = 0,spark = new SparkMD5.ArrayBuffer(),fileChunkHashList = [],fileChunkList = [],fileReader = new FileReader();loadNext();function loadNext() {let start = currentChunk * chunkSize,end = ((start + chunkSize) >= file.size) ? file.size : start + chunkSize;let chunk = blobSlice.call(file, start, end);fileChunkList.push(chunk);fileReader.readAsArrayBuffer(chunk);}function getChunkHash(e) {const chunkSpark = new SparkMD5.ArrayBuffer();chunkSpark.append(e.target.result);fileChunkHashList.push(chunkSpark.end());}// 处理每一块的分片fileReader.onload = function (e) {spark.append(e.target.result);currentChunk++;getChunkHash(e)if (currentChunk < chunks) {loadNext();} else {// 计算完成后,返回结果self.postMessage({fileMd5: spark.end(),fileChunkList,fileChunkHashList,});fileReader.abort();fileReader = null;}}// 读取失败fileReader.onerror = function () {self.postMessage({error: 'wrong'});}
};
http://www.rdtb.cn/news/18657.html

相关文章:

  • 北京城建道桥建设网站平台优化是什么意思
  • 做ppt的软件怎样下载网站新闻最新消息10条
  • 做视频网站视频湖南优化推广
  • 网站如何做排名靠前网络推广员具体做什么的
  • 深圳定制网站建设关键词推广优化
  • 一小时学做网站优化网站排名方法教程
  • 制作静态网站的工具有哪些西安网络科技有限公司
  • 开淘宝的店铺网站怎么做网络暴力事件
  • 免费开源网站系统百度指数的主要用户是
  • 注册网站会员 我们的信息营销关键词有哪些
  • 知名网站建设加盟合作懂得网站推广
  • 网站营销的优缺点长春seo培训
  • 网站建设经典案例郑州网络营销推广
  • 网站建设协议书 印花税什么是seo搜索优化
  • 企业网站配色关键词优化是什么意思?
  • 昌平做网站公司百度学术论文查重官网入口
  • 潮州市网站建设公司新闻式软文经典案例
  • 成都网站建设费用长沙网站优化seo
  • 西部数码网站备案网络软文推广案例
  • 新疆的网站建设有哪些百度知道一下
  • 网站的建设服务武汉seo关键字推广
  • 化妆品网站建设描述南京网站建设
  • 网站建设的可研设计报告如何将网站的关键词排名优化
  • WordPress 云 memcachewindows优化大师是系统软件吗
  • 专门做拼团的网站网络营销官网
  • 湖南住房和城乡建设网门户网站静态网站开发
  • 免费小说网站怎么做商丘seo博客
  • 用腾讯云做淘宝客网站视频下载培训机构营业执照如何办理
  • 那种广告式网站怎么做小广告
  • 深圳网站建设fantodo营销团队公司