nwjs 实现的 分块上传

1、先上核心工具类
/**

* Created by Administrator on 2017/6/12.
*/
let fs = require("fs");
/**
* Created by ZHX on 2017/6/12.
*/
function UploadFile(debug,file,tokenUrl,postUrl,params,progressFun,endFun){
this.tokenUrl = tokenUrl;
this.postUrl = postUrl;
this.params = params;
this.file = file;
this.progressFun = progressFun;
this.endFun = endFun;
this.debugFun = debug;
}

UploadFile.prototype = {
tokenUrl:"",
postUrl:"",
file:"",
progressFun:"",
endFun:"",
buf:null,
// 块大小 10M.
filePiece:10485760,
xhrHandler:"",
XHR:"",
params:{},
// 记录每次开始位置
bytesStart:0,
debugFun:null,
upload:function(){
var self = this;
/** request the server to figure out what's the token for the file: */
var xhr = new XMLHttpRequest;

var vars = {
name: this.file['name'],
size: this.file['size'],
};
var tokenUrl = fAddVars(vars, this.tokenUrl) + "&" + fGetRandom();
xhr.open("GET", tokenUrl, !0);
xhr.onreadystatechange = function() {
if (xhr.readyState != 4 || xhr.status < 200)
return false;
var token;
token = eval("(" + xhr.responseText + ")").token;
self.postUrl = fAddVars(
fMergeJson({token,size:self.file.size,name:self.file.name},self.params),
self.postUrl);
self.uploadFile(0);
}
xhr.send();
},
uploadFile(pos){
this.buf = new Buffer(this.filePiece);
this.bytesStart = pos;
let fileSize = this.file.size;
let self = this;
fs.read(this.file.fd,this.buf,0,this.buf.length,pos,function(err, bytesRead, buffer) {
try{
self.XHR = new XMLHttpRequest;
var _xhr = self.XHR, upload = _xhr.upload;
self.xhrHandler = fExtend(self.loadHandler, self);
upload.addEventListener("progress", self.xhrHandler, !1);
_xhr.addEventListener("load", self.xhrHandler, !1);
_xhr.addEventListener("loadend", self.xhrHandler, !1);
let range = "bytes "+ pos + "-"+ (pos + buffer.length) + "/" + fileSize;
_xhr.open("POST", self.postUrl, !0);
_xhr.setRequestHeader("Content-Range", range);
var blob = new Blob([buffer.buffer]);
self.debugFun(blob);
_xhr.send(blob);
}catch(e)
{
alert(e);
}
});
},
loadHandler(event){
var xhr = this.XHR;
switch(event.type){
case "load":
this.debugFun("load");
var uploaded = 0;
var respJson = null;
var bError = !1;
// try {
//
// } catch(e) {
// bError = this.retriedTimes > 2;
// if (!bError) {
// // this.retry();
// return;
// }
// }
if (xhr.readyState == 4 && (xhr.status == 200 || xhr.status == 308)) {
uploaded = (respJson = eval("(" + xhr.responseText + ")")) ? respJson.start : -1;
} else if (xhr.status < 500 && xhr.status >= 400) {
bError = !0;
} else if (xhr.status < 200) {return;}
/** the response can't process the request, so throws out the error. */
bError = bError || respJson.success == false;

//check whether upload complete yet
if(uploaded < this.file.size -1) {
this.retriedTimes = 0;
this.uploadFile(uploaded);
} else {
this.endFun();
}
break;
case "loaded":
this.debugFun('.......................loading');
break;
case "progress":
this.debugFun('progress-->'+this.bytesStart);
this.progressFun(this.bytesStart + event.loaded);
break;
}
}
};

function fExtend(a, b){
var c = 2 < arguments.length ? [arguments[2]] : null;
return function(){
var d = "string" === typeof a ? b[a] : a,e=c ? [arguments[0]].concat(c) : arguments;
return d.apply(b||d, e);
};
}

function fAddVars(json, url, c) {
var _array = [], _sep = "&", f = function(json, c) {
var e = url ? /\[\]$/.test(url) ? url : url + "[" + c + "]" : c;
"undefined" != e && "undefined" != c
&& _array.push("object" === typeof json
? fAddVars(json, e, !0)
: "[object Function]" === Object.prototype.toString.call(json)
? encodeURIComponent(e) + "=" + encodeURIComponent(json())
: encodeURIComponent(e) + "=" + encodeURIComponent(json))
};
if (!c && url)
_sep = /\?/.test(url) ? /\?$/.test(url) ? "" : "&" : "?",
_array.push(url),
_array.push(fAddVars(json));
else if ("[object Array]" === Object.prototype.toString.call(json)
&& "undefined" != typeof json)
for (var g = 0, c = json.length; g < c; ++g)
f(json[g], g);
else if ("undefined" != typeof json && null !== json && "object" === typeof json)
for (g in json)
f(json[g], g);
else
_array.push(encodeURIComponent(url) + "=" + encodeURIComponent(json));
return _array.join(_sep).replace(/^&/, "").replace(/%20/g, "+")
}

function fGetRandom() {
return (new Date).getTime().toString().substring(8);
}

function fMergeJson(base, extend) {
var result = {};
for (var attr in base)
result[attr] = base[attr];
for (var attr in extend)
result[attr] = extend[attr];
return result;
}

module.exports = UploadFile;

2、file 文件格式:

① 通过fs.stat获取文件信息;
② 通过fs.open获取fd;
代码如下:
fs.stat(vf.path,function(err,stats){
fs.open(vf.path,'r',function(err,fd){
let lu = new LoadUtil(debug,{size:stats.size,name:util.getImageName(vf.path),fd:fd},backIp.ip+vf.tk,backIp.ip+vf.url,
{id:vf.id},
function(pro){
send({type:"progress",data:{id:vf.id,progress:Math.round(pro/stats.size*100)}});
},function(){
send({type:"loaded",data:{id:vf.id}});
});
lu.upload();
});
});


posted @ 2017-06-21 11:20  MvloveYouForever  阅读(397)  评论(0编辑  收藏  举报