这次我们说一下nodejs+angularjs多图片上传的问题
此前也在网站看了很多篇文章,有关的内容说多不多,说少也不少,但我一一试过以后有成功的,也有没有成功的,折磨了我很长时间,最终也是成功实现了,于是想写下这篇文章,分享我的代码,也希望后人不要踏进我的坑。
首先说一下nodejs所以依赖的插件 multiparty 和 fs,可以用npm工具来安装
先贴出我nodejs的后台代码(注意:我的后台代码是写在路由中的)
//生成multiparty对象,并配置上传目标路径
var form = new multiparty.Form({
uploadDir: './public/uploads/',//路径需要对应自己的项目更改
/设置文件保存路径 /
encoding: 'utf-8',/编码设置 /
maxFilesSize: 20000 1024 1024,/设置文件最大值 20MB /
keepExtensions: true,/保留后缀/
});
//上传处理
form.parse(req,function(err,fields,files) {
var filesTmp = JSON.stringify(files,null,2);
console.log(files);
function isType(str) {
if (str.indexOf('.') == -1) {
return '-1';
} else {
var arr = str.split('.');
return arr.pop();
}
}
if (err) {
console.log('parse error: ' + err);
} else {
var inputFile = files.image[0];
var uploadedPath = inputFile.path;
var type = isType(inputFile.originalFilename);
/var dstPath = './public/files/' + inputFile.originalFilename;//真实文件名/
var name = new Date().getTime() + '.' + type; /以上传的时间戳命名/
var dstPath = './public/uploads/' + name; /路径需要对应自己的项目更改/
console.log("type---------" + type);
if (type == "jpg" || type == "png" || type == "exe") {
console.log('可以上传');
//重命名为真实文件名
fs.rename(uploadedPath,dstPath,function(err) {
if (err) {
console.log('rename error: ' + err);
} else {
console.log('上传成功');
}
});
res.writeHead(200,{ 'content-type': 'text/plain;charset=utf-8' });
var data = { "code": "1",'result_code':'SUCCESS',"msg": "上传成功","results": [{ "name": name,"path": "uploads/" + name }] };
console.log(JSON.stringify(data))
res.end(JSON.stringify(data));
} else {
fs.unlink(uploadedPath,function(err) {
if (err) {
return console.error(err);
}
console.log("文件删除成功!");
});
console.log('不能<a href="/tag/shangchuan/" target="_blank" class="keywords">上传</a>' + inputFile.originalFilename);
res.writeHead(200,{ 'content-type': 'text/plain;charset=utf-8' });
var data = { "code": 0,"msg": "<a href="/tag/shangchuan/" target="_blank" class="keywords">上传</a>失败" };
res.end(JSON.stringify(data));
}
}
});
});
然后是angularjs的控制器代码
$scope.reader = new FileReader(); //创建一个FileReader接口
$scope.form = { //用于绑定提交内容,图片或其他数据
image:{},};
$scope.thumb = {}; //用于存放图片的base64
$scope.thumb_default = { //用于循环默认的‘加号'添加图片的框
1111:{}
};
$scope.img_upload = function(files) { //单次提交图片的函数
$scope.guid = (new Date()).valueOf(); //通过时间戳创建一个随机数,作为键名使用
$scope.reader.readAsDataURL(files[0]); //FileReader的方法,把图片转成base64
$scope.reader.onload = function(ev) {
$scope.$apply(function(){
$scope.thumb[$scope.guid] = {
imgSrc : ev.target.result,//接收base64
}
});
};
var data = new FormData(); //以下为像<a href="/tag/houtai/" target="_blank" class="keywords">后台</a>提交<a href="/tag/tupian/" target="_blank" class="keywords">图片</a>数据
data.append('image',files[0]);
data.append('guid',$scope.guid);
$http({
method: 'post',url: '/uploadImg',data:data,headers: {'Content-Type': undefined},transformRequest: angular.identity
}).then(function successCallBack(response) {
if (response.data.result_code == 'SUCCESS') {
$scope.form.image[$scope.guid] = response.data.results[0].path;
$scope.thumb[$scope.guid].status = 'SUCCESS';
console.log($scope.form)
}
if(data.result_code == 'FAIL'){
console.log(data)
}
},function errorCallback(response) {
console.log('网络<a href="/tag/cuowu/" target="_blank" class="keywords">错误</a>')
})
};
$scope.img_del = function(key) { //删除,删除的时候thumb和form里面的图片数据都要删除,避免提交不必要的
var guidArr = [];
for(var p in $scope.thumb){
guidArr.push(p);
}
delete $scope.thumb[guidArr[key]];
delete $scope.form.image[guidArr[key]];
};
$scope.submit_form = function(){ //图片选择完毕后的提交,这个提交并没有提交前面的图片数据,只是提交用户操作完毕后,到底要上传哪些,通过提交键名或者链接,后台来判断最终用户的选择,整个思路也是如此
$http({
method: 'post',url: '/insertImg',data:$scope.form,}).success(function(data) {
console.log(data);
})
};
})
最后是HTML代码