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

网站后台组成网站建设发布教程视频

网站后台组成,网站建设发布教程视频,网上企业登记注册流程,做网站切图的原则是什么目录 1.大文件上传的场景 2.前端实现 2.1 对文件进行分片 2.2 生成hash值#xff08;唯一标识#xff09; 2.3 发送上传文件请求 3.后端实现 3.1 接收分片数据临时存储 3.2 合并分片 4.完成段点续传 4.1修改后端 4.2 修改前端 5.测试 博客主页#xff1a;専心_前端…  目录 1.大文件上传的场景 2.前端实现 2.1 对文件进行分片 2.2 生成hash值唯一标识 2.3 发送上传文件请求 3.后端实现 3.1 接收分片数据临时存储 3.2 合并分片 4.完成段点续传 4.1修改后端 4.2 修改前端 5.测试 博客主页専心_前端,javascript,mysql-CSDN博客  ​系列专栏vue3nodejs 实战--文件上传  ​前端代码仓库jiangjunjie666/my-upload: vue3nodejs 上传文件的项目用于学习 (github.com)  ​后端代码仓库jiangjunjie666/my-upload-server: nodejs上传文件的后端 (github.com)  ​欢迎关注 在上一篇中我们实现了文件的拖拽上传Vue3 Nodejs 实战 文件上传项目--实现拖拽上传-CSDN博客  该篇就讲讲大文件上传的需求场景 1.大文件上传的场景 如果遇到需要上传电影或者视频之类的需求那么上传的文件是非常大的这个时候我们不能说用一个请求就直接将所有的文件传输过去因为这个大文件上传时间相比较来说是比较长的存在很多的弊端假如用户刷新了页面之类的情况这时候上传又需要重头开始上传这对用户以及服务器都是不妥的。 需要解决的基本问题其他的扩展根据需求来定 对大文件进行分片上传上传的实时进度显示上传中断后再次上传跳过已经上传的部分 2.前端实现 2.1 对文件进行分片 对文件进行分片我们用到的是  file.slice(i,j) 这个方法 其中的参数代表的意思就是切割的大小以size单位的i-j 就是切这一段的数据 templateinput typefile changefileChange / /templatescritp import { ref } from vue const fileList ref([]) const file ref([]) const fileChange (e) {console.log(e.target.files[0])//分片file.value e.target.files[0]for (let i 0; i file.value.size; i 1024 * 1024) {fileList.value.push(file.value.slice(i, i 1024 * 1024))} } /script 这样就将文件切成了每个大小为 1024 * 1024 的大小的文件也就是1mb 2.2 生成hash值唯一标识 因为我们进行分片后的文件数据并不能单独成为一个原本的文件一般都是二进制数据我们在分片上传的时候需要临时存储已经上传的文件这时候为了能对应到每个文件需要对每个文件生成对应的文件hash值这里需要用到hash算法项目中大家可以直接使用spark-md5这个库生成文件hash。 总之文件hash的作用就是生成唯一的标识该算法生成的hash值永远不会出现重复 但是同一文件多次生成的都是一样的。 安装 spark-md5 npm i spark-md5 引入生成hash import SparkMD5 from spark-md5const fileMd5 ref()const hash new SparkMD5.ArrayBuffer() // 构建hash值对象const fileReader new FileReader()fileReader.onload () {hash.append(fileReader.result)fileMd5.value hash.end()}fileReader.readAsArrayBuffer(file.value) 2.3 发送上传文件请求 大文件分片上传一般都是二个请求一个是分片上传的请求一个是分片上传完之后的合并请求。 分片上传 const upload async (index) {if (index fileList.value.length) {mergeUpload()return}const formData new FormData()formData.append(chunk, fileList.value[index])formData.append(index, index)formData.append(name, fileMd5.value index) // 临时的二进制文件分片formData.append(filename, fileMd5.value) // 文件名采用hashlet res await http.post(/api/upload_chunk1, formData)if(res.code 200){upload(index1)}else{upload(index) // 失败重新上传 } } 合并分片 const mergeUpload async () {//合并请求let res await http.post(/api/merge_chunk, {filename: fileMd5.value, //最后合并的文件名extname: file.value.type.split(/).pop() //文件后缀})if ((res.code 200)) {file.value nullfileList.value []fileMd5.value ElMessage({type: success,message: 上传成功})} } 3.后端实现 我这边使用的是 multiparty 中间件完成的该需求可以安装一下 npm i multiparty 如果没有看过建的项目可以看看第一期喔Vue3 Nodejs 实战 文件上传项目--实现图片上传-CSDN博客 3.1 接收分片数据临时存储 首先要做的就是利用请求中携带的数据进行创建一个临时保存分片数据的目录目录名可以使用hash值这样可以做到唯一性并且后面实现断点续传也能更方便。 分片上传的数据会被临时保存在 Temp 文件夹中如果windows电脑的话可以 win R 输入 %temp% 就能进入该目录里面保存的都是临时文件。我的做法就是将这个的文件copy一份到对应的目录下然后删除临时文件。 const multiparty require(multiparty) const path require(path) const fs require(fs) exports.upload_chunk1 (req, res, next) {// 二进制数据上传const form new multiparty.Form()form.parse(req, (err, fields, files) {if (err) {next(err)return}//将每一次上传的数据进行统一的存储const oldName files.chunk[0].pathconst newName path.join(__dirname, ../../public/upload/chunk/ fields[filename][0] / fields[name][0])//创建临时存储目录fs.mkdirSync(./public/upload/chunk/ fields[filename][0], {recursive: true})console.log(fields)console.log(files)fs.copyFile(oldName, newName, (err) {if (err) {console.error(err)} else {// 删除源文件fs.unlink(oldName, (err) {if (err) {console.error(err)} else {console.log(文件复制和删除成功)}})}})res.send({code: 200,msg: 分片上传成功})}) }这是刚刚上传的一批二进制文件 3.2 合并分片 合并接口 exports.merge_chunk (req, res, next) {const fields req.bodyconsole.log(fields)thunkStreamMerge(../../public/upload/chunk/ fields.filename, ../../public/upload/ fields.filename . fields.extname)res.send({code: 200,data: /public/upload/ fields.filename . fields.extname}) } 编写一个thunkStreamMerge 函数用来合并分块文件。它接收两参数源文件目录 sourceFiles 和目标文件路径 targetFile。利用 fs.readdirSync 读取源文件目录下的文件列表并根据文件名中的序号排序以确保按正确的顺序合并文件。接着创建一个可写流 (fileWriteStream)用于将所有分块文件的内容写入到目标文件中。这个目标文件路径是由 targetFile 指定的。 // 文件合并 function thunkStreamMerge(sourceFiles, targetFile) {const chunkFilesDir path.join(__dirname, sourceFiles)const chunkTargetDir path.join(__dirname, targetFile)const list fs.readdirSync(chunkFilesDir) //读取目录中的文件const fileList list.sort((a, b) a.split()[1] * 1 - b.split()[1] * 1).map((name) ({name,filePath: path.resolve(chunkFilesDir, name)}))const fileWriteStream fs.createWriteStream(chunkTargetDir)thunkStreamMergeProgress(fileList, fileWriteStream, chunkFilesDir) } thunkStreamMergeProgress 函数是用来处理每个分块文件的函数。它接收三个参数fileList包含了分块文件信息的数组fileWriteStream目标文件的可写流以及可选的 sourceFiles用于删除临时文件目录。 首先函数检查 fileList 是否为空如果为空表示所有分块文件已经合并完成。此时它向目标文件写入一个标识完成了并根据需要删除源文件目录 sourceFiles。 如果 fileList 不为空函数会从中取出第一个文件信息并获取其文件路径。然后它创建一个可读流 (currentReadStream) 来读取该分块文件的内容。 接下来函数使用 .pipe 方法将当前可读流的内容传输到目标文件的可写流中这将逐步将分块文件的内容写入目标文件。 当当前可读流读取完毕end 事件触发后它递归调用 thunkStreamMergeProgress 函数处理下一个分块文件直到所有分块文件都合并到了目标文件中。 //合并每一个分片 function thunkStreamMergeProgress(fileList, fileWriteStream, sourceFiles) {if (!fileList.length) {// thunkStreamMergeProgress(fileList)fileWriteStream.end(完成了)// 删除临时目录if (sourceFiles) fs.rmdirSync(sourceFiles, { recursive: true, force: true })return}const data fileList.shift() // 取第一个数据const { filePath: chunkFilePath } dataconst currentReadStream fs.createReadStream(chunkFilePath) // 读取文件// 把结果往最终的生成文件上进行拼接currentReadStream.pipe(fileWriteStream, { end: false })currentReadStream.on(end, () {// console.log(chunkFilePath);// 拼接完之后进入下一次循环thunkStreamMergeProgress(fileList, fileWriteStream, sourceFiles)}) }这样做完后就能实现基本的文件分片上传以及合并分片了 这是上传的一个视频 4.完成段点续传 4.1修改后端 断点续传的情况就是文件上传至一半时突然做了其他的交互让上传停止了那么下次再上传时就需要重新开始从头上传这样非常消耗时间对用户的体验与服务器的维护都不友好这时候就要判断是否有对应的文件数据直接将对应的索引传给客户端客户端直接从该分片开始传输即可因为我们之前给每个临时文件都加了 hashindex,我们可以读取文件夹目录查找最后的index传输给客户端即可。 当然这种解决方法是因为我没有采用数据库的情况如果采用数据库或者其他的需求基本的实现思路都差不多利用唯一值 hash 进行传输。 后端接口加上一个判断是否为段点传输 exports.upload_chunk1 (req, res, next) {// 二进制数据上传const form new multiparty.Form()form.parse(req, (err, fields, files) {if (err) {next(err)return}let pa path.join(__dirname, ../../public/upload/chunk/ fields[filename][0])console.log(pa)//判断是否为断点续传if (fs.existsSync(pa) parseInt(fields.index[0]) 0) {//存在该目录//返回最大的索引let maxIndex 0let arr fs.readdirSync(pa)for (let i 0; i arr.length; i) {let str parseInt(arr[i].split()[1])console.log(str)if (str maxIndex) {maxIndex str}}res.send({code: 300,msg: 存在该目录请继续上传,index: maxIndex})} else {//将每一次上传的数据进行统一的存储const oldName files.chunk[0].pathconst newName path.join(__dirname, ../../public/upload/chunk/ fields[filename][0] / fields[name][0])//创建临时存储目录fs.mkdirSync(./public/upload/chunk/ fields[filename][0], {recursive: true})console.log(fields)console.log(files)fs.copyFile(oldName, newName, (err) {if (err) {console.error(err)} else {// 删除源文件fs.unlink(oldName, (err) {if (err) {console.error(err)} else {console.log(文件复制和删除成功)}})}})res.send({code: 200,msg: 分片上传成功})}}) } 4.2 修改前端 前端加上进度条发送请求时对相应的数据进行判断即可完成此需求了 分片请求合并请求不变 const upload async (index) {if (index fileList.value.length) {mergeUpload()return}const formData new FormData()formData.append(chunk, fileList.value[index])formData.append(index, index)formData.append(name, fileMd5.value index) // 名字formData.append(filename, fileMd5.value) // 文件名let res await http.post(/api/upload_chunk1, formData)console.log(res)if (res.code 300) {//证明已经存在部分文件percentage.value ((res.index / fileList.value.length) * 100).toFixed(2)upload(res.index 1)} else if (res.code 200) {percentage.value (((index 1) / fileList.value.length) * 100).toFixed(2)upload(index 1)} else {upload(index)} } 加上进度条 templatedivinput typefile changefileChange /div classprogressel-progress :text-insidetrue :stroke-width24 :percentagepercentage statussuccess //div/div /templatescriptlet percentage ref(0)/script 5.测试 我这里选择一个 624Mb的视频 我在上传进度到一半时刷新了页面 分片文件也只有450个 这时候重新选择该视频重新上传 这时候进度条很快就能到对应的进度 后端也没有上传多余的文件直接接着传输速度很快就传输完并且合并成了视频 到这基本的分片传输 断点续传就实现了可能还存在者一些小问题这个大家再项目中根据需求来做相应的改变。 具体的详细代码请大家到仓库下载或者可以去我的主页资源中下载源码。
http://www.dnsts.com.cn/news/109909.html

相关文章:

  • 开发大型网站的流程做网站做什么公司好
  • vs做网站应该新建什么编程入门先学什么好
  • 农业网站建设方案 ppt模板快站app官网下载
  • 中国网站建设排名许昌网页制作
  • 文献综述 php网站开发怎么推广自己的网站?
  • 杂志网站建设响应式网站建设案例
  • 专业做视频的网站注册城乡规划师成绩查询2022
  • 潍坊企业网站模板定制科技软件
  • 提供手机网站制作青岛建设集团 招聘信息网站
  • rest api 做网站福州的网站建设
  • 济南网站建设cnwenhui网站流程图软件
  • 杭州91网站建设软文发布平台有哪些
  • 外贸网站seo推广方案网络规划设计师大纲
  • 专业做数据的网站有哪些招聘58同城招人
  • 河北省建设局网站材料备案郴州seo优化公司
  • 西宁网站搭建专业公司上海装修公司口碑哪家好
  • 怎样去各大网站做淘宝推广wordpress 转为中文版
  • 想做一个电影网站该怎么做网络推广方案xiala11
  • 免费行情软件网站下载大全爱国外网页设计网站
  • 网页设计网站值得推荐主机一键wordpress
  • 江阴市做网站的dede网站404怎么做
  • 广州做网站海珠新科网站蜘蛛爬行统计
  • 淘宝网站开发用到哪些技术找产品做代理都有哪个网站
  • 东莞网站建设(信科网络)代备案网站空间
  • dw做网站有雪花效果私人可注册网站吗
  • 诸暨网站制作有哪些公司合伙合同网站建设协议
  • 兰州专业网站建设公司推广app违法吗
  • 网站原型设计流程1.网站建设基本流程是什么
  • 网站链群怎么做京东网页版
  • 2017年做网站好难汕头站扩建工程