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

js前端分片传输大文件+mongoose后端解析

最近一直在完善mongoose做webserver的项目,其中程序升级要通过前端传输升级包到服务器。
因为第一次写前端代码,分片传输的逻辑,网上一堆,大同小异,而且版本啊,API不一致的问题,导致头疼的很。后面废了九牛二虎之力,想出了用websocket传输二进制升级包,再另加一个消息发送文件名,也就是二进制文件和文本文件分两次发送。

function sendFile(file) {const reader = new FileReader();reader.onload = function(event) {const arrayBuffer = event.target.result;const uint8Array = new Uint8Array(arrayBuffer);const chunkSize = 10240;for (let i = 0; i < uint8Array.length; i += chunkSize) {const chunk = uint8Array.slice(i, i + chunkSize);websocket.send(chunk);}};reader.readAsArrayBuffer(file);
}

今天腾出时间来了,看着这个明显不合理的做法。在网上查了下,同时传输二进制和文本消息的可以用http协议中的multipart/form-data。

# 请求头 - 这个是必须的,需要指定Content-Type为multipart/form-data,指定唯一边界值
Content-Type: multipart/form-data; boundary=${Boundary}# 请求体
--${Boundary}
Content-Disposition: form-data; name="name of file"
Content-Type: application/octet-streambytes of file
--${Boundary}
Content-Disposition: form-data; name="name of pdf"; filename="pdf-file.pdf"
Content-Type: application/octet-streambytes of pdf file
--${Boundary}
Content-Disposition: form-data; name="key"
Content-Type: text/plain;charset=UTF-8text encoded in UTF-8
--${Boundary}--

结果发送小的文本文件貌似没啥问题,发送100多M的大文件,就死活搞不成功了,关键的是不知道咋解析带有boundary的body内容,有个mg_http_next_multipart貌似沾点边,但是没能解析成功。
只好继续百度了,结果发现好像mg_http_upload也有点沾边,但是这个函数的含义,具体用法,又没有注释,真是难啊。
突然想着可以去微软的bing搜索一下,立马就出来了mongoose的官网,里面就写了如何传输需要分片大文件的过程,具体参考mongoose手册。
哎,真是多少年了,还是犯以前在学校的错误。课本概念,例子不弄清楚,就到处去看辅导书。这会是有现成的官网例子不看,成天去看别人的二手资料,也不知道资料是基于哪个API版本。
既然如此,那就下载mongoose手册吧,这下可好了,github又打不开了,真是想干点事,太难了。
那就去gitee吧,一搜,还真有其他好人,早就把mongoose搬过来了,下载简直不要太舒服了。
一切就绪,现用例子试试分片的例子。

document.getElementById('fileMcu').addEventListener('change', function(event) {selectFile = event.target.files[0];var r = new FileReader();r.readAsArrayBuffer(selectFile);r.onload = function() {sendFileData(selectFile.name, new Uint8Array(r.result), 1024*1024);};});var sendFileData = function(name, data, chunkSize) {var sendChunk = function(offset) {var chunk = data.subarray(offset, offset + chunkSize) || '';var opts = {method: 'POST', body: chunk};var url = '/uploadMcu?offset=' + offset + '&file=' + encodeURIComponent(name);fetch(url, opts).then(function(res) {if (res.ok && chunk.length > 0) sendChunk(offset + chunk.length);return res.text();});};sendChunk(0);};

后端C++代码接收文件时,只用一句话,
mg_http_upload(connection, httpReq, &mg_fs_posix, “.”, 999999999);
简直不要太舒服了,都不用自己拼包,自己打开文件写入。
这个时候看了下mg_http_upload的源码,里面就有获取 mg_http_get_var(&hm->query, “offset”, buf, sizeof(buf));
mg_http_get_var(&hm->query, “file”, file, sizeof(file));语句。
这个好熟悉啊,不就是上面的URL后面跟的参数吗?难怪不用自己拼包,打开文件写入呢,你按照正确的格式传输数据,mg_http_upload就能搞定所有的事。
这个周末值了,头疼的事情搞定了。从这个事情明白了,看官网手册的重要性,不得不说老外搞开源项目还是很正规的,值得我们学习。还有就是做一件事情难点很多,哪怕你搞定了最重要的80%,还有不起眼的20%照样能摧毁你,怎么样让自己的知识系统化,全面化,这样才能不断往前推进。

http://www.xdnf.cn/news/394435.html

相关文章:

  • 大数据基础——Ubuntu 安装
  • 洛谷题目:P1673 [USACO05FEB] Part Acquisition S 题解(本题简)
  • 基于zernike 拟合生成包裹训练数据-可自定义拟合的项数
  • Vue Router全局拦截
  • 《Vuejs 设计与实现》第 4 章(响应式系统)( 下 )
  • ES 面试题系列「二」
  • C++ asio网络编程(4)异步读写操作及注意事项
  • (十二)Java枚举类深度解析:从基础到高级应用
  • C++八股——函数对象
  • 工具篇-扣子空间MCP,一键做游戏,一键成曲
  • C/C++实践(五)C++内存管理:从基础到高阶的系统性实现指南
  • 《从零构建一个简易的IOC容器,理解Spring的核心思想》
  • 命令行解释器中shell、bash和zsh的区别
  • LangChain对话链:打造智能多轮对话机器人
  • C 语言报错 xxx incomplete type xxx
  • CTFd CSRF 校验模块解读
  • 表加字段如何不停机
  • NCCL N卡通信机制
  • 《Effective Python》第1章 Pythonic 思维详解——始终用括号包裹单元素元组
  • 用一张网记住局域网核心概念:从拓扑结构到传输介质的具象化理解
  • 懒人美食帮SpringBoot订餐系统开发实现
  • Linux网络编程day9 libevent库
  • 代码随想录算法训练营第60期第三十二天打卡
  • RAII是什么?
  • 大学之大:东京工业大学2025.5.11
  • 误差函数(Error Function)的推导与物理意义
  • 【电机控制器】PY32MD310K18U7TR——ADC、UART
  • AAAI-2025 | 电子科大类比推理助力精准识别!SPAR:基于自提示类比推理的无人机目标探测技术
  • Java 线程池原理
  • 解决stm32HAL库使用vscode打开,识别不到头文件及uint8_t等问题