node.js分片上传文件
前端 :
<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分片上传文件的更多相关文章
- Node.js:上传文件,服务端如何获取文件上传进度
内容概述 multer是常用的Express文件上传中间件.服务端如何获取文件上传的进度,是使用的过程中,很常见的一个问题.在SF上也有同学问了类似问题<nodejs multer有没有查看文件 ...
- Node.js——异步上传文件
前台代码 submit() { var file = this.$refs.fileUpload.files[0]; var formData = new FormData(); formData.a ...
- 科普文:Node.js 如何上传文件到后端服务【转】
原文链接 https://www.yuque.com/egg/nodejs/httpclient-upload 背景 互联网时代,无数服务是基于 HTTP 协议进行通信的. 除了常见的 前端浏览器 - ...
- js能否上传文件夹
文件夹上传:从前端到后端 文件上传是 Web 开发肯定会碰到的问题,而文件夹上传则更加难缠.网上关于文件夹上传的资料多集中在前端,缺少对于后端的关注,然后讲某个后端框架文件上传的文章又不会涉及文件夹. ...
- 利用ajaxfileupload.js异步上传文件
1.引入ajaxfileupload.js 2.html代码 <input type="file" id="enclosure" name="e ...
- js获取上传文件内容(未完待续)
js 获取上传文件的字节数及内容 <div> 上传文件 : <input type="file" name = "file" id = &qu ...
- django实现分片上传文件
目标:利用django实现上传文件功能 1,先设置路由系统 urls.py from django.conf.urls import url,include from django.contrib i ...
- Atitit.js获取上传文件全路径
Atitit.js获取上传文件全路径 1. 默认的value只能获取文件名..安全原因.. 1 2. Firefox浏览器的读取 1 3. Html5 的file api 2 4. 解决方法::使用a ...
- js获取上传文件内容
js 获取上传文件的字节数及内容 <div> 上传文件 : <input type="file" name = "file" id = &qu ...
随机推荐
- leetcode 106. 从中序与后序遍历序列构造二叉树(Construct Binary Tree from Inorder and Postorder Traversal)
目录 题目描述: 示例: 解法: 题目描述: 根据一棵树的中序遍历与后序遍历构造二叉树. 注意: 你可以假设树中没有重复的元素. 示例: 给出 中序遍历 inorder = [9,3,15,20,7] ...
- 【bzoj2140】: 稳定婚姻 图论-tarjan
[bzoj2140]: 稳定婚姻 哎..都是模板题.. 一眼看过去 哇 二分图哎 然后发现好像并不能匈牙利算法 自己xjb画两张图,发现二分图左向右连配偶的边,然后右向左连交往过的边 然后如果Bi G ...
- winform datagridview某一列设为自动宽度
如果用displayedcells只会使看见的数据自动列宽,滚动条往下发现后面的没有自动列宽,所以要用allcells就不会出现这个问题
- poj2154(polya定理+欧拉函数)
题目链接:http://poj.org/problem?id=2154 题意:n 种颜色的珠子构成一个长为 n 的环,每种颜色珠子个数无限,也不一定要用上所有颜色,旋转可以得到状态只算一种,问有多少种 ...
- [llvm] LLVM 核心类简明示例 : llvm::Value && llvm::Type && llvm::Constant
LLVM 核心类简明示例 : llvm::Value && llvm::Type && llvm::Constant llvm核心类位于 include/llvm/IR ...
- Python-list()之remove()/pop() I /del()
代码块 remove #remove删除首个符合条件的元素,并不删除特定的索引. n =[1,2,2,3,4,5] n.remove(3) print (n) #输出 [1, 2, 2, 4, 5] ...
- hdu6437 Videos 费用流
题目传送门 题目大意: 给出n,每天有n个小时.有m种电影,每个电影有开始时间和结束时间,和01两种种类,k个人,每一部电影只能被一个人看,会获得一个快乐值wi,如果一个人连续看两部相同种类的电影,快 ...
- Codeforces - 662A 思路巧妙的异或
题意:给你\(n\)堆石子玩尼姆博弈,每堆石子可以是\(a_i\)也可以是\(b_i\),选择概率相等且每堆选择相互独立,求先手必胜(异或不为0)的概率 首先需要找出一种优雅的策略表示方法(利用异或的 ...
- Python——爬取瓜子二手车
# coding:utf8 # author:Jery # datetime:2019/5/1 5:16 # software:PyCharm # function:爬取瓜子二手车 import re ...
- 利用httpClient发起https请求
HttpClientBuilder b = HttpClientBuilder.create();// setup a Trust Strategy that allows all certifica ...