nodejs上传文件和下载文件到本地(一)——文件上传篇
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了nodejs上传文件和下载文件到本地(一)——文件上传篇,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含18907字,纯文字阅读大概需要28分钟。
内容图文
![nodejs上传文件和下载文件到本地(一)——文件上传篇](/upload/InfoBanner/zyjiaocheng/831/4b58f475bb83452b8cddae4fd21726ed.jpg)
继上一篇设置端口之后,公司又有了新的开发需求了,原来用java写过一套的升级包管理服务,现在因为新的项目需要,java代码太冗余了,所有要求用nodejs来完成升级包管理和运维服务,这个新的任务,自然而然就落到我身上了。
还好之前接触过nodejs的东西,做起来不至于一脸懵逼,这次也算是深入学习一下nodejs,数据库用的是Mysql。
主要上床这一块的主要代码了
页面的布局的布局代码
<div class="mainIndex" ng-controller="mainController">
<div class="container-fluid main" style="width:100%;height:100%;">
<div id="header" class="row-fluid">
<div class="col-md-7" id="header_left" ><span>{{"titleLogin"|translate}}</span></div>
<div class="col-md-5" id="header_right"><span><span><img src="../images/user.png">{{"user"|translate}}:admin</span><span ng-click="exit()">{{"writeOff"|translate}}</span></span></div>
</div>
<div id="mainBody">
<div style="height:200px;">
<div class="Text-Font-title">{{"uploadPackage"|translate}}</div>
<div style="margin-left:10px;">
<table id="filetable">
<tr>
<td class="Text-Font-first">{{"productType"|translate}}:</td>
<td>
<select ng-model="productType" class="commonSelect" ng-change="productTypeChange()">
<option ng-repeat="x in productTypes" >{{x}}</option>
</select>
<span class="importantflag">*</span>
</td>
<td class="Text-Font">{{"fileSelect"|translate}}:</td>
<td>
<!--<form id="upload" method="post" enctype="multipart/form-data">-->
<!--<input id="uploadFileSelect" type=file style="display:none;width:250px; *height:32px;"-->
<!--onchange="jQuery('#uploadFilePath').val(jQuery('#uploadFileSelect').val())"/>-->
<!--<input type="text" readonly="readonly" id="uploadFilePath" class="input-text"/>-->
<!--<input class="uploadFileButton" type="button" value={{"submit"|translate}}-->
<!--onclick="jQuery('#uploadFileSelect').click()" />-->
<!--</form>-->
<form id="upload" name="form" style="width:268px;">
<div class="button" ngf-pattern="'*'" ngf-select="uploadFileSelect()" ng-model="uploadFile"
style="width:250px; height:32px;float: left;">
<input id="uploadFilePath" ng-model="uploadFilePath" class="input-text" style="width:248px; height:26px;" />
</div>
<div class="importantflag" style="float:right;margin-top: 4px;">*</div>
</form>
</td>
</tr>
<tr id="romInput" style="display: none">
<td class="Text-Font">{{"productDevice"|translate}}:</td>
<td><input type="text" ng-model="productDevice" class="textInput"/> <span class="importantflag">*</span></td>
<td class="Text-Font">{{"versionCode"|translate}}:</td>
<td><input type="text" ng-model="versionCode" class="textInput_version"/> <span class="importantflag">*</span></td>
<!--<td class="Text-Font">{{"md5"|translate}}:</td>-->
<!--<td><input type="text" ng-model="md5" class="textInput_version"/><span class="importantflag">*</span></td>-->
</tr>
<tr>
<td class="Text-Font">{{"fileDesc"|translate}}:</td>
<td><input type="text" ng-model="fileDesc" class="textInput"/> <span class="importantflag">*</span></td>
<td class="Text-Font">{{"versionDesc"|translate}}:</td>
<td><input type="text" ng-model="versionDesc" class="textInput_version"/><span class="importantflag">*</span></td>
</tr>
<tr>
<td></td>
<td><button ng-click="UpgradePackageUpload()" class="uploadFileButton" >{{"upload"|translate}}</button></td>
</tr>
<tr id='progress' style="display:none;">
<td class="Text-Font">{{"uploadProgress"|translate}}:</td>
<td >
<div id="progress_bar">
<div id='bar'></div>
</div>
</td>
</tr>
</table>
</div>
</div>
<div id="package_info">
<div class="Text-Font-title">{{"upgradePackageInfo"|translate}}</div>
<div style="margin-left:10px;margin-top:6px;">
<span class="Text-Font-first">{{"productType"|translate}}:</span>
<select ng-model="productTypeSelect" class="commonSelect" ng-options="x for x in productTypes">
</select>
<!--<input class="textInput" type="text" ng-model="productTypeSelect">-->
<button class="uploadFileButton" ng-click="search()">{{"search"|translate}}</button>
</div>
<div style="margin-top:10px;width:90%;margin-left:10px;overflow: auto;" id="package_info_table">
<table id="table"></table>
</div>
</div>
</div>
<div id="footer"></div>
</div>
</div>
因为项目不同的产品类型有不同的输入内容,所以每一次选择不同的产品,有不同的界面布局
不同的产品升级包采用表格的形式来呈现和管理
function createTable(url) {
var $table = $('#table');
$table.bootstrapTable('destroy');
$table.bootstrapTable({
url: url,
queryParams: function (params) {//请求服务器时所传的参数
return {
pageSize: params.limit, //每一页的数据行数,默认是上面设置的10(pageSize)
pageIndex: params.offset + 1, //当前页面,默认是上面设置的1(pageNumber)
}
},
pageNumber: 1,
cache: false,
pageSize: 5,
pageList: [2, 5, 10, 15, 20, 25],//分页步进值
pagination: true,
sidePagination: 'server',//指定服务器端分页
locale: language.tableLanguage,//en-US英文,zh-CN中文
columns: [
{
title: language.productType,
field: 'productType',
align: 'center',
},
{
title: language.versionNum,
field: 'versionNum',
align: 'center',
},
{
title: language.packageSize,
field: 'packageSize',
align: 'center'
},
{
title: language.packageName,
field: 'packageName',
align: 'center'
},
{
title: language.uploadPath,
field: 'uploadPath',
align: 'center'
},
{
title: language.uploadTime,
field: 'uploadTime',
align: 'center'
},
{
title: language.downloadTimes,
field: 'downloadTimes',
align: 'center'
},
{
title: language.fileDesc,
field: 'packageDesc',
align: 'center'
},
{
title: language.versionDesc,
field: 'versionDesc',
align: 'center'
},
{
title: language.operation,
field: 'operate',
align: 'center',
formatter: operateFormatter,
events: operateEvents
}
],
});
}
这就是创建表格的方法,不过还有删除功能,所以还有一些辅助的方法
function operateFormatter(val, row, index) {
if (lang == "zh" || lang == "zh-cn") {
return '<input type="button" class="del" value="删除" /> ';
} else {
return '<input type="button" class="del" value=delete /> ';
}
};
//删除行数据后,重建表格
function deletePackageInfo(productType, versionNum) {
var productionType;
for (var i in productionAllDta) {
if (productionAllDta[i].typeName == productType) {
productionType = productionAllDta[i].typeCode;
break;
}
}
createTable("/fxrest/packages/" + productionType + "/" + versionNum);
};
//按产品类型查询,并在表格中显示
$scope.productTypeSelect = "";
$scope.search = function () {
var productionType;
for (var i in productionAllDta) {
if (productionAllDta[i].typeName == $scope.productTypeSelect) {
productionType = productionAllDta[i].typeCode;
break;
}
}
createTable("/fxrest/packages/" + productionType);
};
//动态设置表格所在div高度
var hh = document.body.clientHeight;
var packageInfoHeight = hh * 0.9 - 180;
var packageInfoTableHeight = packageInfoHeight - 40;
$("#package_info").height(packageInfoHeight);
$("#package_info_table").height(packageInfoTableHeight);
window.onresize = function () {
var hh = document.body.clientHeight;
var packageInfoHeight = hh * 0.9 - 180;
var packageInfoTableHeight = packageInfoHeight - 40;
$("#package_info").height(packageInfoHeight);
$("#package_info_table").height(packageInfoTableHeight);
}
//响应点击事件
window.operateEvents = {
'click .del': function (e, value, row, index) {
if (confirm(language.deleteConfirm)) {
deletePackageInfo(row.productType, row.versionNum);
}
}
};
主要就是上传部分了,上传部分的代码其实很简单
$scope.upload = function (productType, fileDesc, versionDesc, upFileValue, versionCode, productDevice, file) {
console.log("----------uploadFlag---------" + uploadFlag);
if (uploadFlag == "" || uploadFlag == "uploadSuccess") {
var obj = productType + ":" + fileDesc + ":" + versionDesc + ":" + upFileValue + ":" + versionCode + ":" + productDevice;
$('#progress').show();
var schedule = 0;
var up = Upload.upload({
//请求接收的地址
url: '/fxrest/UpgradePackageUpload' + obj,
//上传的文件
method: 'POST',
file: file
}).progress(function (evt) {
//进度条
var progressPercentage = parseInt(100.0 * evt.loaded / evt.total);
// console.log('progess:' + progressPercentage + '%' + evt.config.file.name);
schedule = progressPercentage;
$('#bar').css('width', schedule + '%');
$('#bar')[0].innerHTML = schedule + '%';
console.log("================uploadFlag==========" + schedule);
uploadFlag = "uploading";
if (schedule == 99) {
$('#bar').css('width', '100%');
$('#bar')[0].innerHTML = '100%';
uploadFlag = "uploadSuccess";
} else if (schedule == 100) {
$('#bar').css('width', '100%');
$('#bar')[0].innerHTML = '100%';
uploadFlag = "uploadSuccess";
}
}).success(function (data, status, headers, config) {
//上传成功
$('#progress').hide();
console.log('file ' + config.file.name + 'uploaded. Response: ' + JSON.stringify(data));
if (data.result == "0") {
alert(language.uploadFail);
} else if (data.result == "1") {
alert(language.uploadSuccess);
console.log("uploadFlag1:" + uploadFlag);
clear();
console.log("uploadFlag2:" + uploadFlag);
createTable('/fxrest/packages');
} else if (data.result == "3") {
alert(language.fileNameExits);
}
}).error(function (data, status, headers, config) {
//上传失败
// console.log('error status: ' + status);
alert(language.uploadFail);
});
$scope.cancelFile = up.abort;
} else if (uploadFlag == "uploading") {
alert(language.fileIsUploading);
}
};
这里是请求的部分,下面看看服务器是这么接收的
router.post('/UpgradePackageUpload:obj', function (req, res) {
logger.info("mainController 请求升级");
var param = req.params.obj;
logger.info("param>>>>>" + param);
var productType = param.split(":")[0];
var fileDesc = param.split(":")[1];
var versionDesc = param.split(":")[2];
var upFileValue = param.split(":")[3];
var versionCode = param.split(":")[4];
//var md5 = param.split(":")[5];
var productDevice = param.split(":")[5];
mainService.UpgradePackageUpload(productType, fileDesc, versionDesc, upFileValue, versionCode, productDevice, req, res);
});
这里是控制器的部分,将字段都处理好
module.exports.UpgradePackageUpload = function (productType, fileDesc, versionDesc, upFileValue, versionCode, productDevice, req, res) {
//上传文件到服务器
console.log(upFileValue);
upload(productType, fileDesc, versionDesc, upFileValue, versionCode, productDevice, req, res);
};
function upload(productType, fileDesc, versionDesc, upFileValue, versionCode, productDevice, req, res) {
var flag;
var uploadDir = "";
var linux = os.platform() == 'linux' ? 1 : 0;
if (linux) {
uploadDir = "/etc/sysconfig/workspace";
} else {
uploadDir = "E:/workspace";//测试路径
}
var exists = fs.existsSync(uploadDir);
console.log(exists ? "目录存在" : "目录不存在");
if (!exists) {
fs.mkdirSync(uploadDir);
}
var form = new formidable.IncomingForm();
form.uploadDir = uploadDir;//必须设置
form.encoding = 'utf-8';
form.multiples = true;//设置为多文件上传
form.keepExtensions = true;
var selectPackageName, packageName;
var downloadTimes = "0", versionNum = "1";
var allFiles = [];
// var fileInfo={
// productType : "",
// packageDesc:"",
// versionDesc:"",
// packageName : "",
// uploadPath : "",
// packageSize : "",
// versionNum:"",
// downloadTimes:"",
// };
form.on('file', function (name, file) {
// packageName = file.name;
// var fileInfo={};
// fileInfo.packageName = packageName;
// fileInfo.uploadPath = uploadDir + "/" + file.name;
// fileInfo.packageSize = (file.size/1024).toFixed(2);
// fileInfo.productType = productType;
// fileInfo.packageDesc = fileDesc;
// fileInfo.versionDesc = versionDesc;
// fileInfo.downloadTimes = downloadTimes;
// fileInfo.versionNum = versionNum;
allFiles.push(file);
});
form.parse(req, function (error, fields, files) {
if (error) {
flag = false;
} else {
allFiles.forEach(function (file, index) {
console.log("file:" + JSON.stringify(file));
var oldPath = file.path;
var newPath = uploadDir + "/" + file.name;
var md5;
fs.rename(oldPath, newPath, function (err) {
if (err) {
logger.info("改名失败");
} else {
fileUploadDao.selectUpGradePackagePackageName(upFileValue, function (err, vals) {
if (err) {
flag = false;
logger.info("查询文件名失败:" + err);
res.send({result: 0});
} else if (vals.length == 0) {
if (productType == "IPVT-ROM-01") {
var rs = fs.createReadStream(newPath);
var hash = crypto.createHash('md5');
rs.on('data', hash.update.bind(hash));
rs.on('end', function () {
md5 = hash.digest('hex');
fileUploadDao.getNodeIp(function (err, vals) {
if (vals && vals.length > 0) {
console.log(vals);
var url = "http://" + vals[0].node_ip + ":6061/download/" + file.name
var result = {
productDevice: productDevice,
fileUrl: url,
fileSize: file.size,
md5: md5,
release_note: versionDesc,
versionCode: versionCode
}
logger.info("rom上传信息>>>>>>>>" + JSON.stringify(result))
var postUrl = "http://" + vals[0].node_ip + ":9003/uploadRomByUrl";
postUrl = postUrl + "?&productDevice=" + productDevice + "&fileUrl=" + url + "&fileSize=" + file.size + "&md5=" + md5 + "&release_note=" + versionDesc + "&versionCode=" + versionCode
rest.postRes(postUrl, result, function (data) {
if (data.result == true) {
logger.info("上传请求发送成功");
fileUploadDao.selectUpGradePackageVersionNum(productType, function (err, vals) {
logger.info("start db operation....")
if (err) {
flag = false;
logger.info("查询数据库失败=" + err);
if (flag) {
res.send({result: 1});
} else {
res.send({result: 0});
}
}
var fileInfo = {};
fileInfo.packageName = file.name;
fileInfo.uploadPath = uploadDir + "/" + file.name;
fileInfo.packageSize = (file.size / 1024).toFixed(2);
fileInfo.productType = productType;
fileInfo.packageDesc = fileDesc;
fileInfo.versionDesc = versionDesc;
fileInfo.downloadTimes = downloadTimes;
fileInfo.versionNum = versionNum;
if (vals && vals.length == 0) {
fileUploadDao.insertUpGradePackageInfo(fileInfo, function (err, vals) {
if (err) {
logger.info("保存数据库失败:" + err);
res.send({result: 0})
} else {
fileUploadDao.insertUpGradePackageRomInfo(productType, fileInfo.versionNum, productDevice, versionCode, function (err, vals) {
if (err) {
logger.error("insertUpGradePackageRomInfo失败:" + err);
deletePackInfo(productType, fileInfo.versionNum, res);
res.send({result: 0});
} else {
res.send({result: 1});
}
});
}
});
} else {
fileInfo.versionNum = vals[vals.length - 1].versionNum + 1;
fileUploadDao.insertUpGradePackageInfo(fileInfo, function (err, vals) {
if (err) {
logger.info("更新数据库失败:" + err);
res.send({result: 0})
} else {
fileUploadDao.insertUpGradePackageRomInfo(productType, fileInfo.versionNum, productDevice, versionCode, function (err, vals) {
if (err) {
logger.error("insertUpGradePackageRomInfo失败:" + err);
deletePackInfo(productType, fileInfo.versionNum, res);
res.send({result: 0});
} else {
res.send({result: 1});
}
});
}
});
}
});
} else {
logger.info("上传请求发送失败")
res.send({result: 0});
}
});
} else {
logger.info("查询本级节点IP失败")
res.send({result: 0});
}
});
});
} else {
fileUploadDao.selectUpGradePackageVersionNum(productType, function (err, vals) {
if (err) {
flag = false;
logger.info("查询数据库失败=" + err);
if (flag) {
res.send({result: 1});
} else {
res.send({result: 0});
}
}
var fileInfo = {};
fileInfo.packageName = file.name;
fileInfo.uploadPath = uploadDir + "/" + file.name;
fileInfo.packageSize = (file.size / 1024).toFixed(2);
fileInfo.productType = productType;
fileInfo.packageDesc = fileDesc;
fileInfo.versionDesc = versionDesc;
fileInfo.downloadTimes = downloadTimes;
fileInfo.versionNum = versionNum;
if (vals && vals.length == 0) {
fileUploadDao.insertUpGradePackageInfo(fileInfo, function (err, vals) {
flag = true;
if (err) {
logger.info("保存数据库失败:" + err);
flag = false;
}
if (flag) {
res.send({result: 1});
} else {
res.send({result: 0});
}
});
} else {
fileInfo.versionNum = vals[vals.length - 1].versionNum + 1;
fileUploadDao.insertUpGradePackageInfo(fileInfo, function (err, vals) {
flag = true;
if (err) {
flag = false;
logger.info("更新数据库失败:" + err);
}
if (flag) {
res.send({result: 1});
} else {
res.send({result: 0});
}
});
}
});
}
} else {
res.send({result: 3});
}
});
}
});
});
}
});
form.on("end", function () {
});
function deletePackInfo(productType, versionNum, res) {
suspend(function*() {
try {
yield upgradePackageInfoDao.deletePackageInfo(productType, versionNum, resume())
res.send({result: 0});
} catch (e) {
res.send({result: 0});
}
})();
}
这是服务的部分,代码很多很长,因为要处理不同的产品,还有一个产品需要和另外一台服务器连接,有别人的服务区管理,所以还得将问价转给别人一份
接下来是删除上传的文件
module.exports.deletePackageInfo = function (productType, versionNum, pageSize, pageIndex, res) {
logger.info("按条件删除升级包信息,productType:" + productType + "versionNum:" + versionNum + ",pageSize:" + pageSize + ",pageIndex:" + pageIndex);
var uploadDir = "";
var linux = os.platform() == 'linux' ? 1 : 0;
if (linux) {
uploadDir = "/etc/sysconfig/workspace";
} else {
uploadDir = "E:\\workspace";//测试路径
}
if (productType == "IPVT-ROM-01") {
logger.info("进入IPVT-ROM-01 删除操作")
suspend(function*() {
try {
var romInfo = yield upgradePackageInfoDao.getRomInfoByProductTypeAndVersionNum(productType, versionNum, resume());
logger.info("romInfo>>>" + JSON.stringify(romInfo))
logger.info("romInfo.length>>>" + romInfo.length)
if (romInfo && romInfo.length > 0) {
fileUploadDao.getNodeIp(function (err, vals) {
if (vals && vals.length > 0) {
logger.info("节点IP:" + vals);
var postUrl = "http://" + vals[0].node_ip + ":9003/delVersionByVcode";
postUrl = postUrl + "?&productDevice=" + romInfo[0].productDevice + "&versionCode=" + romInfo[0].versionCode
rest.postRes(postUrl, null, function (data) {
if (data.result == true) {
logger.info("删除请求发送成功");
suspend(function*() {
try {
//删除上传路径下的升级包
var packageName = yield upgradePackageInfoDao.getPackageNameByProductTypeAndVersionNum(productType, versionNum, resume());
fs.unlinkSync(uploadDir + "/" + packageName);
//删除数据库里记录信息
yield upgradePackageInfoDao.deleteRomInfo(productType, versionNum, resume())
var result = yield upgradePackageInfoDao.deletePackageInfo(productType, versionNum, pageSize, pageIndex, resume());
var allDatas = yield upgradePackageInfoDao.getAllPackageInfos(resume());
var data = {};
data.total = allDatas.length;
data.rows = result;
res.json(data);
} catch (e) {
res.json({total: 0, rows: []});
}
})();
} else {
logger.info("删除请求发送失败")
res.json({total: 0, rows: []});
}
});
}
});
} else {
suspend(function*() {
try {
logger.info("没有找到rom表对应的信息")
var packageName = yield upgradePackageInfoDao.getPackageNameByProductTypeAndVersionNum(productType, versionNum, resume());
fs.unlinkSync(uploadDir + "/" + packageName);
//删除数据库里记录信息
var result = yield upgradePackageInfoDao.deletePackageInfo(productType, versionNum, pageSize, pageIndex, resume());
var allDatas = yield upgradePackageInfoDao.getAllPackageInfos(resume());
var data = {};
data.total = allDatas.length;
data.rows = result;
res.json(data);
} catch (e) {
logger.info("删除失败")
res.json({total: 0, rows: []});
}
})();
}
} catch (e) {
res.json({total: 0, rows: []});
}
})();
} else {
suspend(function*() {
try {
logger.info("进入非 IPVT-ROM-01 删除操作")
//删除上传路径下的升级包
var packageName = yield upgradePackageInfoDao.getPackageNameByProductTypeAndVersionNum(productType, versionNum, resume());
fs.unlinkSync(uploadDir + "/" + packageName);
//删除数据库里记录信息
var result = yield upgradePackageInfoDao.deletePackageInfo(productType, versionNum, pageSize, pageIndex, resume());
var allDatas = yield upgradePackageInfoDao.getAllPackageInfos(resume());
var data = {};
data.total = allDatas.length;
data.rows = result;
res.json(data);
} catch (e) {
logger.info("删除失败")
res.json({total: 0, rows: []});
}
})();
}
};
基本就完成基本功能啦,具体详细的代码,等我写完下一篇关于下载的部分之后,可以看我的git项目。
内容总结
以上是互联网集市为您收集整理的nodejs上传文件和下载文件到本地(一)——文件上传篇全部内容,希望文章能够帮你解决nodejs上传文件和下载文件到本地(一)——文件上传篇所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。