我是平均堆栈的新手。我想知道如何通过angularjs将图像文件上传到数据库(mongoose)。如果可能的话,请提供一些代码。我在互联网上搜索过但我没有找到合适的代码。
答案 0 :(得分:16)
你有很多方法和工具可以达到你想要的效果。我把其中一个放在这里:
对于这个,我使用angular-file-upload作为客户端。所以你需要在你的控制器中使用这个:
$scope.onFileSelect = function(image) {
if (angular.isArray(image)) {
image = image[0];
}
// This is how I handle file types in client side
if (image.type !== 'image/png' && image.type !== 'image/jpeg') {
alert('Only PNG and JPEG are accepted.');
return;
}
$scope.uploadInProgress = true;
$scope.uploadProgress = 0;
$scope.upload = $upload.upload({
url: '/upload/image',
method: 'POST',
file: image
}).progress(function(event) {
$scope.uploadProgress = Math.floor(event.loaded / event.total);
$scope.$apply();
}).success(function(data, status, headers, config) {
$scope.uploadInProgress = false;
// If you need uploaded file immediately
$scope.uploadedImage = JSON.parse(data);
}).error(function(err) {
$scope.uploadInProgress = false;
console.log('Error uploading file: ' + err.message || err);
});
};
在视图中跟随代码(我还为现代浏览器添加了文件类型处理程序):
Upload image <input type="file" data-ng-file-select="onFileSelect($files)" accept="image/png, image/jpeg">
<span data-ng-if="uploadInProgress">Upload progress: {{ uploadProgress }}</span>
<img data-ng-src="uploadedImage" data-ng-if="uploadedImage">
对于服务器端,我使用了node-multiparty。
这就是您在服务器端路线上所需要的:
app.route('/upload/image')
.post(upload.postImage);
在服务器端控制器中:
var uuid = require('node-uuid'),
multiparty = require('multiparty'),
fs = require('fs');
exports.postImage = function(req, res) {
var form = new multiparty.Form();
form.parse(req, function(err, fields, files) {
var file = files.file[0];
var contentType = file.headers['content-type'];
var tmpPath = file.path;
var extIndex = tmpPath.lastIndexOf('.');
var extension = (extIndex < 0) ? '' : tmpPath.substr(extIndex);
// uuid is for generating unique filenames.
var fileName = uuid.v4() + extension;
var destPath = 'path/to/where/you/want/to/store/your/files/' + fileName;
// Server side file type checker.
if (contentType !== 'image/png' && contentType !== 'image/jpeg') {
fs.unlink(tmpPath);
return res.status(400).send('Unsupported file type.');
}
fs.rename(tmpPath, destPath, function(err) {
if (err) {
return res.status(400).send('Image is not saved:');
}
return res.json(destPath);
});
});
};
正如您所看到的,我将上传的文件存储在文件系统中,因此我只使用node-uuid为它们指定了唯一的名称。如果要将文件直接存储在数据库中,则不需要uuid,在这种情况下,只需使用Buffer数据类型。
另外请注意将angularFileUpload
添加到角度模块依赖项中。
答案 1 :(得分:4)
我收到了ENOENT和EXDEV错误。解决这些后,下面的代码对我有用。
var uuid = require('node-uuid'),
multiparty = require('multiparty'),
fs = require('fs');
var form = new multiparty.Form();
form.parse(req, function(err, fields, files) {
var file = files.file[0];
var contentType = file.headers['content-type'];
var tmpPath = file.path;
var extIndex = tmpPath.lastIndexOf('.');
var extension = (extIndex < 0) ? '' : tmpPath.substr(extIndex);
// uuid is for generating unique filenames.
var fileName = uuid.v4() + extension;
var destPath = appRoot +'/../public/images/profile_images/' + fileName;
// Server side file type checker.
if (contentType !== 'image/png' && contentType !== 'image/jpeg') {
fs.unlink(tmpPath);
return res.status(400).send('Unsupported file type.');
}
var is = fs.createReadStream(tmpPath);
var os = fs.createWriteStream(destPath);
if(is.pipe(os)) {
fs.unlink(tmpPath, function (err) { //To unlink the file from temp path after copy
if (err) {
console.log(err);
}
});
return res.json(destPath);
}else
return res.json('File not uploaded');
});
变量'appRoot'在express.js
中执行path = require('path');
global.appRoot = path.resolve(__dirname);