前端 :

<html>

<head>
<title>分片上传文件</title>
</head> <body>
<div class="hei-bg" style="display:block;">
<div class="user-info" style="display:block;">
<div class="tc">请上传大文件</div>
<div class="user-pic picw320">
<input id="uppic" type="file">
</div>
<div id="jd" class="jdb">进度</div> <div>
<input type="button" value="确定" id="userbtn" class="bg-main tc userbtn">
</div>
</div>
</div>
</body>
<script src="/javascripts/jquery.min.js"></script>
<script>
$(function () {
$('#userbtn').on('click', async function () {
var d1 = new Date();
let file = $("#uppic")[0].files[0], //上传文件主体
name = file.name, //文件名
size = file.size, //总大小
succeed = 0, //当前上传数
shardSize = 1 * 1024 * 1024, //以1MB为一个分片
shardCount = Math.ceil(size / shardSize); //总片数 let attr = [];
try {
for (let item = 0; item < shardCount; ++item) {
await fn(item); //同步
// attr.push(fn(item)); //异步
}
await Promise.all(attr); //异步 $('.jdb').append(' 上传成功');
var d2 = new Date();
console.log(parseInt(d2 - d1) / 1000);
} catch (err) {
$('.jdb').html(err);
console.log(err);
} function fn(item) {
return new Promise((resolve, reject) => {
var i = item;
var start = i * shardSize, //当前分片开始下标
end = Math.min(size, start + shardSize); //结束下标 //构造一个表单,FormData是HTML5新增的
var form = new FormData();
form.append("data", file.slice(start, end)); //slice方法用于切出文件的一部分
form.append("name", name); //文件名字
form.append("total", shardCount); //总片数
form.append("index", i + 1); //当前片数
//Ajax提交 $.ajax({
url: "/sliceUpload",
type: "POST",
data: form,
timeout: 120 * 1000,
async: false, //同步
processData: false, //很重要,告诉jquery不要对form进行处理
contentType: false, //很重要,指定为false才能形成正确的Content-Type
success: function (data) {
++succeed;
if (typeof (data) == 'string') {
try {
data = JSON.parse(data);
console.log(data.msg);
} catch (e) {
console.log(data);
}
}
//生成当前进度百分比
var jd = `${Math.round(succeed / shardCount * 100)}%`;
$('.jdb').html(jd);
/*如果是线上,去掉定时,直接callback(),
这样写是为方便,本地测试看到进度条变化
因为本地做上传测试是秒传,没有时间等待*/
setTimeout(resolve, 50);
}
});
})
}
});
});
</script> </html>

服务器端:

async function sliceUpload(req, res) {
var fs = require('fs');
var multiparty = require('multiparty'); //文件上传模块
var form = new multiparty.Form(); //新建表单
//设置编辑
form.encoding = 'utf-8';
//设置文件存储路径
form.uploadDir = "temp/"; // "Uploads/";
//设置单文件大小限制
// form.maxFilesSize = 200 * 1024 * 1024;
/*form.parse表单解析函数,fields是生成数组用获传过参数,files是bolb文件名称和路径*/
try {
let [fields, files] = await new Promise((resolve, reject) => {
form.parse(req, (err, fields, files) => {
if (err) reject('test err');
resolve([fields, files]);
})
}) files = files['data'][0]; //获取bolb文件
var index = fields['index'][0]; //当前片数
var total = fields['total'][0]; //总片数
var name = fields['name'][0]; //文件名称
var url = 'temp/' + name + index; //临时bolb文件新名字
fs.renameSync(files.path, url); //修改临时文件名字 var pathname = 'Uploads/' + name; //上传文件存放位置和名称
if (index == total) { //当最后一个分片上传成功,进行合并
// 检查文件是存在,如果存在,重新设置名称
let NonExist = await new Promise((resolve, reject) => {
fs.access(pathname, fs.F_OK, (err) => {
resolve(err);
});
})
if (!NonExist) {
var myDate = Date.now();
pathname = 'Uploads/' + myDate + name;
}
logs.info('上传文件:' + pathname);
/*进行合并文件,先创建可写流,再把所有BOLB文件读出来,
流入可写流,生成文件
fs.createWriteStream创建可写流
aname是存放所有生成bolb文件路径数组:
['Uploads/3G.rar1','Uploads/3G.rar2',...]
*/
var writeStream = fs.createWriteStream(pathname);
var aname = [];
for (let i = 1; i <= total; i++) {
let url = 'temp/' + name + i;
let data = await new Promise(function (resolve, reject) {
fs.readFile(url, function (error, data) {
if (error) reject(error);
resolve(data);
});
});
//把数据写入流里
writeStream.write(data);
//删除生成临时bolb文件
fs.unlink(url, () => {});
}
writeStream.end();
//返回给客服端,上传成功
var data = JSON.stringify({
'code': 0,
'msg': '上传成功'
});
res.send(data); //返回数据
} else { //还没有上传文件,请继续上传
var data = JSON.stringify({
'code': 1,
'msg': '继续上传'
});
res.send(data); //返回数据
}
} catch (e) {
logs.info(e);
res.send(e); //返回数据
}
}

node.js分片上传文件的更多相关文章

  1. Node.js:上传文件,服务端如何获取文件上传进度

    内容概述 multer是常用的Express文件上传中间件.服务端如何获取文件上传的进度,是使用的过程中,很常见的一个问题.在SF上也有同学问了类似问题<nodejs multer有没有查看文件 ...

  2. Node.js——异步上传文件

    前台代码 submit() { var file = this.$refs.fileUpload.files[0]; var formData = new FormData(); formData.a ...

  3. 科普文:Node.js 如何上传文件到后端服务【转】

    原文链接 https://www.yuque.com/egg/nodejs/httpclient-upload 背景 互联网时代,无数服务是基于 HTTP 协议进行通信的. 除了常见的 前端浏览器 - ...

  4. js能否上传文件夹

    文件夹上传:从前端到后端 文件上传是 Web 开发肯定会碰到的问题,而文件夹上传则更加难缠.网上关于文件夹上传的资料多集中在前端,缺少对于后端的关注,然后讲某个后端框架文件上传的文章又不会涉及文件夹. ...

  5. 利用ajaxfileupload.js异步上传文件

    1.引入ajaxfileupload.js 2.html代码 <input type="file" id="enclosure" name="e ...

  6. js获取上传文件内容(未完待续)

    js 获取上传文件的字节数及内容 <div> 上传文件 : <input type="file" name = "file" id = &qu ...

  7. django实现分片上传文件

    目标:利用django实现上传文件功能 1,先设置路由系统 urls.py from django.conf.urls import url,include from django.contrib i ...

  8. Atitit.js获取上传文件全路径

    Atitit.js获取上传文件全路径 1. 默认的value只能获取文件名..安全原因.. 1 2. Firefox浏览器的读取 1 3. Html5 的file api 2 4. 解决方法::使用a ...

  9. js获取上传文件内容

    js 获取上传文件的字节数及内容 <div> 上传文件 : <input type="file" name = "file" id = &qu ...

随机推荐

  1. 用Python写一个随机密码生成器

    # /bin/python3 import sys import time import random strs = [ i for i in range(32,128) ] #产生密码的ASCII码 ...

  2. HDU6301-2018ACM暑假多校联合训练1004-Distinct Values

    题意是一个长度为n的序列,给你m组区间(l,r),在这个区间里不能填入重复的数字,同时使整个序列字典序最小 同学用的优先队列,标程里使用的是贪心同时使用set维护答案序列 贪心是先采用pre数组来确定 ...

  3. pycharm 不显示代码提示

    1.检查是否代码本身有问题. 2.检查代码提示是否成功开启. 3.检查IDE省电模式是否关闭状态. 4.使用快捷键:ctrl+j.ctrl+space.alt+/ 其他(不能安装): 1.检查是否Py ...

  4. 题解 P3252 【[JLOI2012]树】

    \(\Huge{[JLOI2012]树}\) 题目描述 在这个问题中,给定一个值S和一棵树.在树的每个节点有一个正整数,问有多少条路径的节点总和达到S.路径中节点的深度必须是升序的.假设节点1是根节点 ...

  5. SDUT OJ 顺序表应用1:多余元素删除之移位算法

    顺序表应用1:多余元素删除之移位算法 Time Limit: 1000 ms Memory Limit: 650 KiB Submit Statistic Discuss Problem Descri ...

  6. 条目七《如果容器中包含了通过new操作创建的指针,切记在容器对象析构前将指针delete掉》

    如果容器中包含了通过new操作创建的指针,切记在容器对象析构前将指针delete掉 在STL中容器是智能的,可以在容器销毁时自动调用容器里对象的析构函数来销毁容器存储的对象. STL的容器虽然比较智能 ...

  7. elasticsearch head 连接不到elasticsearch

    配置好head后看到没有正常连接到elasticsearch.  重启后效果:

  8. redis中使用lua脚本

    lua脚本 Lua是一个高效的轻量级脚本语言,用标准C语言编写并以源代码形式开放, 其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能 使用脚本的好处 1.减少网络开销,在Lua脚 ...

  9. 康奈尔大学CFD课程

    先上链接:https://confluence.cornell.edu/display/SIMULATION/Home 如果不会FQ,可以去edx:https://courses.edx.org/co ...

  10. LeetCode8. 字符串转整数 (atoi)

    8. 字符串转整数 (atoi) 描述 实现 atoi,将字符串转为整数. 在找到第一个非空字符之前,需要移除掉字符串中的空格字符.如果第一个非空字符是正号或负号,选取该符号,并将其与后面尽可能多的连 ...