前端 :

<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. Java 中的main方法

    public static void main(String args[]) public:表示此方法可以被外部所调用. static:表示此方法可以由类名称直接调用. void:主方法是程序的起点, ...

  2. Python变量类型的强制转换

    当我们需要对数据的类型转换时,只需要将数据类型作为函数名即可. 下面给出的函数可以执行数据类型之间的转换,函数返回一个新的对象,表示转换的值 函数格式 使用示例 描述 int(x [,base]) i ...

  3. 1. C/C++项目一

    需求: 使用C语言封装string 字符串,实现字符串的增.删.改.查等API函数. 要求: 不能使用 string 库函数,所有库函数必须自己手动实现. [项目实现] myString.h 代码如下 ...

  4. 前端CSS的基本素养

    前端开发的三驾马车——html.css.js,先谈谈CSS CSS 前期:解决布局.特效.兼容问题 中级:网站风格的制定.色调.模块.布局方式.交互方式.逻辑设计等 高级:模块命名.类的命名.文件的组 ...

  5. SqlServer批量插入(SqlBulkCopy、表值参数)

    之前做项目需要用到数据库的批量插入,于是就研究了一下,现在做个总结. 创建了一个用来测试的Student表: CREATE TABLE [dbo].[Student]( [ID] [int] PRIM ...

  6. Java 实现发送邮件

    javax.mail.AuthenticationFailedException: 530 Error: A secure connection is requiered(such as ssl). ...

  7. MacOs桌面自动被打乱的原因

    1 系统设置--Mission Control -- 自动根据最近使用情况排序的勾勾去掉

  8. 理解Javascript_02_执行上下文01

    执行上下文又名执行上下文环境 JS中为什么会产生这个概念呢,先来看一下下面的这段代码: 通过执行发现,第一句代码报了ReferenceError,第二句和第三句代码是undefined,由于undef ...

  9. JavaWeb学习笔记(十四)—— 使用JDBC处理MySQL大数据

    一.什么是大数据 所谓大数据,就是大的字节数据,或大的字符数据.大数据也称之为LOB(Large Objects),LOB又分为:clob和blob,clob用于存储大文本,blob用于存储二进制数据 ...

  10. python之函数(一)

    python有很多内置函数,可以直接调用.比如type(), len(), range(),max(), min(), filter().内置函数我们就先不多提,我们主要介绍自定义函数. 1. 函数的 ...