如何使用mean js将图像文件上传到mongoose数据库

时间:2021-05-30 17:09:37

I am new to the mean stack. I want to know how to upload an image file to the database(mongoose) through angularjs. If possible, please provide me with some code. I have searched the internet but I haven't found any suitable code.

我是平均堆栈的新手。我想知道如何通过angularjs将图像文件上传到数据库(mongoose)。如果可能的话,请提供一些代码。我搜索过互联网,但我没有找到合适的代码。

2 个解决方案

#1


16  

You have plenty ways and tools to achieve what you want. I put one of them here:

你有很多方法和工具来实现你想要的。我把其中一个放在这里:

For this one I use angular-file-upload as client side. So you need this one in your controller:

对于这个,我使用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);
            });
        };

And following code in your view (I also added file type handler for modern browsers):

并在视图中跟随代码(我还为现代浏览器添加了文件类型处理程序):

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">

For server side, I used node-multiparty.

对于服务器端,我使用了node-multiparty。

And this is what you need in your server side route:

这就是您在服务器端路由中所需要的:

app.route('/upload/image')
    .post(upload.postImage);

And in server side controller:

在服务器端控制器中:

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);
        });
    });
};

As you can see, I store uploaded files in file system, so I just used node-uuid to give them unique name. If you want to store your files directly in database, you don't need uuid, and in that case, just use Buffer data type. Also please take care of things like adding angularFileUpload to your angular module dependencies.

如您所见,我将上传的文件存储在文件系统中,因此我只使用node-uuid为它们指定唯一的名称。如果要将文件直接存储在数据库中,则不需要uuid,在这种情况下,只需使用Buffer数据类型。另外请注意将angularFileUpload添加到角度模块依赖项中。

#2


4  

I got ENOENT and EXDEV errors. After solving these, below code worked for me.

我收到了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');
});

for variable 'appRoot' do below in express.js

对于变量'appRoot',请在express.js中进行

path = require('path');
global.appRoot = path.resolve(__dirname);

#1


16  

You have plenty ways and tools to achieve what you want. I put one of them here:

你有很多方法和工具来实现你想要的。我把其中一个放在这里:

For this one I use angular-file-upload as client side. So you need this one in your controller:

对于这个,我使用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);
            });
        };

And following code in your view (I also added file type handler for modern browsers):

并在视图中跟随代码(我还为现代浏览器添加了文件类型处理程序):

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">

For server side, I used node-multiparty.

对于服务器端,我使用了node-multiparty。

And this is what you need in your server side route:

这就是您在服务器端路由中所需要的:

app.route('/upload/image')
    .post(upload.postImage);

And in server side controller:

在服务器端控制器中:

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);
        });
    });
};

As you can see, I store uploaded files in file system, so I just used node-uuid to give them unique name. If you want to store your files directly in database, you don't need uuid, and in that case, just use Buffer data type. Also please take care of things like adding angularFileUpload to your angular module dependencies.

如您所见,我将上传的文件存储在文件系统中,因此我只使用node-uuid为它们指定唯一的名称。如果要将文件直接存储在数据库中,则不需要uuid,在这种情况下,只需使用Buffer数据类型。另外请注意将angularFileUpload添加到角度模块依赖项中。

#2


4  

I got ENOENT and EXDEV errors. After solving these, below code worked for me.

我收到了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');
});

for variable 'appRoot' do below in express.js

对于变量'appRoot',请在express.js中进行

path = require('path');
global.appRoot = path.resolve(__dirname);