Nodejs 第五十八章(大文件上传)

image.png

在现代网站中,越来越多的个性化图片,视频,去展示,因此我们的网站一般都会支持文件上传。

文件上传的方案

  1. 大文件上传:将大文件切分成较小的片段(通常称为分片或块),然后逐个上传这些分片。这种方法可以提高上传的稳定性,因为如果某个分片上传失败,只需要重新上传该分片而不需要重新上传整个文件。同时,分片上传还可以利用多个网络连接并行上传多个分片,提高上传速度。
  2. 断点续传:在上传过程中,如果网络中断或上传被中止,断点续传技术可以记录已成功上传的分片信息,以便在恢复上传时继续上传未完成的部分,而不需要重新上传整个文件。这种技术可以大大减少上传失败的影响,并节省时间和带宽。

前端实现

<input id="file" type="file"> <!--用来上传文件-->

监听change事件获取文件 file,实现一个方法 chunkFun 用来切片

const file = document.getElementById('file')
file.addEventListener('change', (event) => {const file = event.target.files[0] //获取文件信息const chunks = chunkFun(file)uploadFile(chunks)
})

文件切片 file 接受文件对象,注意file的底层是继承于blob的因此他可以调用blob的方法,slice进行切片,size就是每个切片的大小,我这里用了4MB 实际可以根据项目情况来

const chunkFun = (file, size = 1024 * 1024 * 4) => {const chunks = []for (let i = 0; i < file.size; i += size) {chunks.push(file.slice(i, i + size))}return chunks
}

循环调用接口上传,并且存储一些信息,当前分片的索引,注意file必须写在最后一个,因为nodejs端的multer 会按照顺序去读的,不然读不到参数, 最后通过promise.all 并发发送请求,等待所有请求发送完成,通知后端合并切片。

const uploadFile = (chunks) => {const List = []for (let i = 0; i < chunks.length; i++) {const formData = new FormData()formData.append('index', i)formData.append('total', chunks.length)formData.append('fileName', 'xiezhen')formData.append('file', chunks[i])List.push(fetch('http://127.0.0.1:3000/up', {method: 'POST',body: formData}))}Promise.all(List).then(res => {fetch('http://127.0.0.1:3000/merge',{method: 'POST',headers:{'Content-Type': 'application/json'},body:JSON.stringify({fileName: 'xiaoManXieZhen',})}).then(res => {console.log(res)})})
}

nodejs端实现

安装依赖

  1. express 帮我们启动服务,并且提供接口
  2. multer 读取文件,存储
  3. cors 解决跨域

引入模块

import express from 'express'
import multer from 'multer'
import cors from 'cors'
import fs from 'node:fs'
import path from 'node:path'

提供两个接口

  1. up 用来存储切片
  2. merge 合并切片

初始化 multer.diskStorage

  • destination 存储的目录
  • filename 存储的文件名(我是通过index-文件名存储的你也可以改)

合并逻辑

读取upload目录下面的所有文件 也就是所有的切片

0-xiezhen
1-xiezhen
2-xiezhen
3-xiezhen

读取之后返回的是一个数组,但是读取的时候会乱序,所以从小到大排个序,用了sort,排完序之后,读取每个切片的内容,通过 fs.appendFileSync 合并至一个文件,最后删除合并过的切片 完成。respect

const storage = multer.diskStorage({destination: (req, file, cb) => {cb(null, 'uploads/')},filename: (req, file, cb) => {cb(null, `${req.body.index}-${req.body.fileName}`)}
})
const upload = multer({ storage })
const app = express()app.use(cors())
app.use(express.json())app.post('/up', upload.single('file'), (req, res) => {res.send('ok')
})app.post('/merge', async (req, res) => {const uploadPath = './uploads'let files = fs.readdirSync(path.join(process.cwd(), uploadPath))files = files.sort((a, b) => a.split('-')[0] - b.split('-')[0])const writePath = path.join(process.cwd(), `video`, `${req.body.fileName}.mp4`)files.forEach((item) => {fs.appendFileSync(writePath, fs.readFileSync(path.join(process.cwd(), uploadPath, item)))fs.unlinkSync(path.join(process.cwd(), uploadPath, item))})res.send('ok')
})app.listen(3000, () => {console.log('Server is running on port 3000')
})

image.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/279812.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【3DsMax】UVW展开——以制作牙膏盒为例

效果 步骤 1. 从网上下载牙膏盒贴图&#xff0c;我下载的贴图地址为&#xff08;牙膏盒贴图链接&#xff09; 2. 打开3DsMax&#xff0c;创建一个长方体&#xff0c;设置长宽高分别为180、45、40毫米 打开材质编辑器&#xff0c;点击漫反射后的按钮 双击“位图” 将材质赋予长…

113 链接集10--ctrl+左键单击多选

1.ctrl+左键单击多选,单击单选 精简代码 <div class="model-list"><div@mousedown.prevent="handleClick(item, $event)"class="model-list-item"v-for="item in modelList":key="item.id":class="{ model-a…

QT6实现创建与操作sqlite数据库及读取实例(一)

一.Qt为SQL数据库提供支持的基本模块&#xff08;Qt SQL&#xff09; Qt SQL的API分为不同层&#xff1a; 驱动层 SQL API层 用户接口层 1.驱动层 对于Qt 是基于C来实现的框架&#xff0c;该层主要包括QSqlDriver&#xff0c;QSqlDriverCreator,QSqlDriverCreatorBase,QSqlPlug…

C++初阶 | [九] list 及 其模拟实现

摘要&#xff1a;介绍 list 容器&#xff0c;list 模拟实现&#xff0c;list与vector的对比 list&#xff08;带头双向循环列表&#xff09; 导入&#xff1a;list 的成员函数基本上与 vector 类似&#xff0c;具体内容可以查看相关文档(cplusplus.com/reference/list/list/)&…

UE4_官方动画内容示例1.1_使用动画资产

对一个SkeletalMeshActor进行设置&#xff0c;设置好之后&#xff0c;可以通过该Actor的细节&#xff08;Details&#xff09;面板播放指定的动画序列&#xff08;AnimationSequence&#xff09;资产&#xff08;例如让Actor翻跟斗并做开合跳&#xff09;。 骨架网格体定义&am…

后端系统开发之——接口参数校验

今天难得双更&#xff0c;大家点个关注捧个场 原文地址&#xff1a;后端系统开发之——接口参数校验 - Pleasure的博客 下面是正文内容&#xff1a; 前言 在上一篇文章中提到了接口的开发&#xff0c;虽然是完成了&#xff0c;但还是缺少一些细节——传入参数的校验。 即用户…

2024计算机二级Python6

在Python语言中局部变量可以是任意标识符&#xff0c;因为局部变量在函数结束时相当于被销毁&#xff0c;即使与全局变量同名也可以正常运行 在函数内部引用数字类型全局变量时&#xff0c;必须使用global保留字声明 函数内部引用组合类型全局变量时&#xff0c;可以不通过gl…

HTML实现卷轴动画完整源码附注释

动画效果截图 页面的html结构代码 <!DOCTYPE html> <html> <head lang=

Python之Web开发中级教程----ubuntu中下载安装Postman

Python之Web开发中级教程----ubuntu中下载安装Postman PostMan 是一款功能强大的网页调试与发送网页 HTTP 请求的 Chrome 插件&#xff0c;可以直接去对我们写出来的路由和视图函数进行调试&#xff0c;作为后端程序员是必须要知道的一个工具。 查看ubuntu系统中是否已经安装了…

微信小程序订阅消息(一次性订阅消息)

1、准备工作 登录微信公众平台–>订阅消息–>在公共模板库中选中一个模版–>将模版id复制&#xff0c;前后端都需要。 点击详情–>查看详细内容模版 复制给后端 2、相关api的使用 前端使用&#xff1a;wx.requestSubscribeMessage wx.openSetting wx.getSetti…

51单片机-蜂鸣器

1.蜂鸣器的介绍 无源蜂鸣器不能一直通电&#xff0c;无源蜂鸣器内部的线圈较小&#xff0c;易烧坏 蜂鸣器的驱动 达林顿晶体管&#xff08;npn型&#xff09; 应用&#xff1a; 按下独立按键同时蜂鸣器响起提示音&#xff0c;数码管显示对应的独立按键键码 #include <REG…

微信小程序 ---- 慕尚花坊 结算支付

结算支付 01. 配置分包并跳转到结算页面 思路分析&#xff1a; 随着项目功能的增加&#xff0c;项目体积也随着增大&#xff0c;从而影响小程序的加载速度&#xff0c;影响用户的体验。 因此我们需要将 结算支付 功能配置成一个分包&#xff0c; 当用户在访问设置页面时&a…

交叉注意力融合时域、频域特征的FFT + CNN -BiLSTM-CrossAttention电能质量扰动识别模型

往期精彩内容&#xff1a; 电能质量扰动信号数据介绍与分类-Python实现-CSDN博客 Python电能质量扰动信号分类(一)基于LSTM模型的一维信号分类-CSDN博客 Python电能质量扰动信号分类(二)基于CNN模型的一维信号分类-CSDN博客 Python电能质量扰动信号分类(三)基于Transformer…

消息队列面试题

目录 1. 为什么使用消息队列 2. 消息队列的缺点 3. 消息队列如何选型&#xff1f; 4. 如何保证消息队列是高可用的 5. 如何保证消息不被重复消费&#xff08;见第二条&#xff09; 6. 如何保证消息的可靠性传输&#xff1f; 7. 如何保证消息的顺序性&#xff08;即消息幂…

【RabbitMQ | 第六篇】消息重复消费问题及解决方案

文章目录 6.消息重复消费问题6.1问题介绍6.2解决思路6.3将该消息存储到Redis6.3.1将id存入string&#xff08;单消费者场景&#xff09;&#xff08;1&#xff09;实现思路&#xff08;2&#xff09;问题 6.3.2将id存入list中&#xff08;多消费场景&#xff09;&#xff08;1&…

部署应用到K8s集群(未完)

&#xff08;等熟悉一番再来写&#xff0c;因为按小时结算的。。。&#xff09; 1 、 kubectl run 启动 nginx 应用 kubectl run nginx --imagenginx:latest 2、将本地机器的80端口转发到集群中名为nginx的Pod的80端口 kubectl port-forward --address 0.0.0.0 pod/nginx 80:8…

最新ChatGPT/GPT4科研应用与AI绘图及论文高效写作教程

原文链接&#xff1a;最新ChatGPT/GPT4科研应用与AI绘图及论文高效写作教程https://mp.weixin.qq.com/s?__bizMzUzNTczMDMxMg&mid2247598050&idx5&sn70fd3f5946d581ad9c1363295b130ef5&chksmfa823e05cdf5b713baf9cf1381bfb2455ad675a0b21e194bef8b76f35d6aa77…

milvus安装

milvus安装 sudo curl -L “https://github.com/docker/compose/releases/download/1.29.2/docker-compose- $ (uname -s)- $ (uname -m)” -o /usr/local/bin/docker-compose sudo chmod x /usr/local/bin/docker-compose sudo ln -s /usr/local/bin/docker-compose /usr/bin/…

Mysql数据库概念与安装

目录 一、数据库概述 1、数据库的基本概念 2、数据库管理系统&#xff08;DBMS&#xff09; 2.1 数据库管理系统概念 2.2 数据库管理系统工作模式 3、数据库系统&#xff08;DBS&#xff09; 3.1 数据库系统概念 3.2 数据库系统发展史 4、关系型数据库与非关系型数据库…

【刷题】滑动窗口入门

送给大家一句话&#xff1a; 那脑袋里的智慧&#xff0c;就像打火石里的火花一样&#xff0c;不去打它是不肯出来的。——莎士比亚 滑动窗口入门 认识滑动窗口Leetcode 209. 长度最小的子数组题目描述算法思路 Leetcode 3. 无重复字符的最长子串题目描述算法思路 Leetcode 1004…