使用Mongoose,Express和AngularJS上传图像

Dai*_*imz 18 mongoose mongodb node.js express angularjs

我知道以前已经多次询问过这个问题,而且我已经阅读了几乎所有关于这个主题的内容,即:

/sf/answers/1751570621/

使用Node.js,Express和Mongoose上传图像

这是迄今为止我发现的最好的.我的问题是他们仍然不是很清楚,关于这一点在网上的文档很少,讨论似乎针对的是比我更先进的人.

所以我真的很喜欢它,如果有人可以请告诉我如何使用Mongoose,Express和AngularJS上传图像.我实际上正在使用MEAN fullstack.(这个发生器准确无误 - https://github.com/DaftMonk/generator-angular-fullstack)

AddController:

'use strict';

angular.module('lumicaApp')
  .controller('ProjectAddCtrl', ['$scope', '$location', '$log', 'projectsModel', 'users', 'types', function ($scope, $location, $log, projectsModel, users, types) {
    $scope.dismiss = function () {
      $scope.$dismiss();
    };

        $scope.users = users;
        $scope.types = types;

    $scope.project = {
            name: null,
            type: null,
            images: {
                thumbnail: null // I want to add the uploaded images _id here to reference with mongoose populate.
            },
            users: null
        };

        $scope.save = function () {
            $log.info($scope.project);
            projectsModel.post($scope.project).then(function (project) {
        $scope.$dismiss();
            });
        }

  }]);
Run Code Online (Sandbox Code Playgroud)

我想添加Images ID引用,project.images.thumbnail但我想使用以下Schema将所有信息存储在Image Object中:

'use strict';

    var mongoose = require('mongoose'),
        Schema = mongoose.Schema;

    var ImageSchema = new Schema({
      fileName: String,
      url: String,
      contentType: String,
      size: String,
      dimensions: String
    });

    module.exports = mongoose.model('Image', ImageSchema);
Run Code Online (Sandbox Code Playgroud)

我还在我的凉亭包中添加了以下https://github.com/nervgh/angular-file-upload.

正如我所说,我无法弄清楚如何将它们联系在一起.我甚至不确定我要做的是否也是正确的方法.

-------------------------------------------------- ------------------------ \

更新:

这是我现在拥有的,我已经添加了一些评论,详细说明了我希望它如何工作,遗憾的是我仍然没有设法让这个工作,我甚至无法让图像开始上传,更不用说上传到S3了.很抱歉是一个痛苦,但我只是觉得这特别令人困惑,这让我感到惊讶.

客户端/应用/人/添加/ add.controller.js

'use strict';

angular.module('lumicaApp')
    .controller('AddPersonCtrl', ['$scope', '$http', '$location', '$window', '$log', 'Auth', 'FileUploader', 'projects', 'usersModel', function ($scope, $http, $location, $window, $log, Auth, FileUploader, projects, usersModel) {
        $scope.dismiss = function () {
            $scope.$dismiss();
        };

        $scope.newResource = {};

        // Upload Profile Image
        $scope.onUploadSelect = function($files) {
            $scope.newResource.newUploadName = $files[0].name;

            $http
                .post('/api/uploads', {
                    uploadName: newResource.newUploadName,
                    upload: newResource.newUpload
                })
                .success(function(data) {
                    newResource.upload = data; // To be saved later
                });
        };

        $log.info($scope.newResource);

        //Get Projects List
        $scope.projects = projects;

        //Register New User
        $scope.user = {};
        $scope.errors = {};


        $scope.register = function(form) {
            $scope.submitted = true;

            if(form.$valid) {
                Auth.createUser({
                    firstName: $scope.user.firstName,
                    lastName: $scope.user.lastName,
                    username: $scope.user.username,
                    profileImage: $scope.user.profileImage, // I want to add the _id reference for the image here to I can populate it with 'ImageSchema' using mongoose to get the image details(Name, URL, FileSize, ContentType, ETC)
                    assigned: {
                        teams: null,
                        projects: $scope.user.assigned.projects
                    },
                    email: $scope.user.email,
                    password: $scope.user.password
                })
                    .then( function() {
                        // Account created, redirect to home
                        //$location.path('/');
                        $scope.$dismiss();
                    })
                    .catch( function(err) {
                        err = err.data;
                        $scope.errors = {};

                        // Update validity of form fields that match the mongoose errors
                        angular.forEach(err.errors, function(error, field) {
                            form[field].$setValidity('mongoose', false);
                            $scope.errors[field] = error.message;
                        });
                    });
            }
        };

        $scope.loginOauth = function(provider) {
            $window.location.href = '/auth/' + provider;
        };

    }]);
Run Code Online (Sandbox Code Playgroud)

server/api/image/image.model.js我想在这里存储所有图像信息并使用它来填充profileImage人控制器.

'use strict';

    var mongoose = require('mongoose'),
        Schema = mongoose.Schema;

    var ImageSchema = new Schema({
      fileName: String,
      url: String, // Should store the URL of image on S3.
      contentType: String,
      size: String,
      dimensions: String
    });

    module.exports = mongoose.model('Image', ImageSchema);
Run Code Online (Sandbox Code Playgroud)

客户端/应用/人/添加/ add.jade

.modal-header
    h3.modal-title Add {{ title }}
.modal-body
    form(id="add-user" name='form', ng-submit='register(form)', novalidate='')
        .form-group(ng-class='{ "has-success": form.firstName.$valid && submitted,\
        "has-error": form.firstName.$invalid && submitted }')
            label First Name
            input.form-control(type='text', name='firstName', ng-model='user.firstName', required='')
            p.help-block(ng-show='form.firstName.$error.required && submitted')
                | First name is required

        .form-group(ng-class='{ "has-success": form.lastName.$valid && submitted,\
        "has-error": form.lastName.$invalid && submitted }')
            label Last Name
            input.form-control(type='text', name='lastName', ng-model='user.lastName', required='')
            p.help-block(ng-show='form.lastName.$error.required && submitted')
                | Last name is required

        .form-group(ng-class='{ "has-success": form.username.$valid && submitted,\
        "has-error": form.username.$invalid && submitted }')
            label Username
            input.form-control(type='text', name='username', ng-model='user.username', required='')
            p.help-block(ng-show='form.username.$error.required && submitted')
                | Last name is required

        // Upload Profile Picture Here
        .form-group
            label Profile Image
            input(type="file" ng-file-select="onUploadSelect($files)" ng-model="newResource.newUpload")

        .form-group(ng-class='{ "has-success": form.email.$valid && submitted,\
        "has-error": form.email.$invalid && submitted }')
            label Email
            input.form-control(type='email', name='email', ng-model='user.email', required='', mongoose-error='')
            p.help-block(ng-show='form.email.$error.email && submitted')
                | Doesn't look like a valid email.
            p.help-block(ng-show='form.email.$error.required && submitted')
                | What's your email address?
            p.help-block(ng-show='form.email.$error.mongoose')
                | {{ errors.email }}

        .form-group(ng-class='{ "has-success": form.password.$valid && submitted,\
        "has-error": form.password.$invalid && submitted }')
            label Password
            input.form-control(type='password', name='password', ng-model='user.password', ng-minlength='3', required='', mongoose-error='')
            p.help-block(ng-show='(form.password.$error.minlength || form.password.$error.required) && submitted')
                | Password must be at least 3 characters.
            p.help-block(ng-show='form.password.$error.mongoose')
                | {{ errors.password }}

        .form-group
            label Assign Project(s)
            br
            select(multiple ng-options="project._id as project.name for project in projects" ng-model="user.assigned.projects")
        button.btn.btn-primary(ng-submit='register(form)') Save

    pre(ng-bind="user | json")
.modal-footer
    button.btn.btn-primary(type="submit" form="add-user") Save
    button.btn.btn-warning(ng-click='dismiss()') Cancel
Run Code Online (Sandbox Code Playgroud)

服务器/ API /上传/ index.js

'use strict';

var express = require('express');
var controller = require('./upload.controller');

var router = express.Router();

//router.get('/', controller.index);
//router.get('/:id', controller.show);
router.post('/', controller.create);
//router.put('/:id', controller.update);
//router.patch('/:id', controller.update);
//router.delete('/:id', controller.destroy);

module.exports = router;
Run Code Online (Sandbox Code Playgroud)

服务器/ API /上传/ upload.controller.js

'use strict';

var _ = require('lodash');
//var Upload = require('./upload.model');
var aws = require('aws-sdk');
var config = require('../../config/environment');
var randomString = require('../../components/randomString');

// Creates a new upload in the DB.
exports.create = function(req, res) {
    var s3 = new aws.S3();
    var folder = randomString.generate(20); // I guess I do this because when the user downloads the file it will have the original file name.
    var matches = req.body.upload.match(/data:([A-Za-z-+\/].+);base64,(.+)/);

    if (matches === null || matches.length !== 3) {
        return handleError(res, 'Invalid input string');
    }

    var uploadBody = new Buffer(matches[2], 'base64');

    var params = {
        Bucket: config.aws.bucketName,
        Key: folder + '/' + req.body.uploadName,
        Body: uploadBody,
        ACL:'public-read'
    };

    s3.putObject(params, function(err, data) {
        if (err)
            console.log(err)
        else {
            console.log("Successfully uploaded data to my-uploads/" + folder + '/' + req.body.uploadName);
            return res.json({
                name: req.body.uploadName,
                bucket: config.aws.bucketName,
                key: folder
            });
        }
    });
};

function handleError(res, err) {
    return res.send(500, err);
}
Run Code Online (Sandbox Code Playgroud)

服务器/配置/环境/ development.js

aws: {
        key: 'XXXXXXXXXXXX',
        secret: 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
        region: 'sydney',
        bucketName: 'my-uploads'
    }
Run Code Online (Sandbox Code Playgroud)

Mic*_*ins 11

所有这些代码都直接来自一个项目,该项目在很大程度上依赖于大型文件上传和图像.绝对结帐https://github.com/nervgh/angular-file-upload

在我看来某处:

<div class="form-group">
  <label>File Upload</label>
  <input type="file" ng-file-select="onUploadSelect($files)" ng-model="newResource.newUpload">
</div>
Run Code Online (Sandbox Code Playgroud)

angularFileUpload然后使用模块我在我的控制器中:

$scope.onUploadSelect = function($files) {
  $scope.newResource.newUploadName = $files[0].name;
};
Run Code Online (Sandbox Code Playgroud)

https://github.com/nervgh/angular-file-upload

当用户点击上传时,会在我发送要上传的文件的位置执行此操作:

$http
  .post('/api/uploads', {
    uploadName: newResource.newUploadName,
    upload: newResource.newUpload
  })
  .success(function(data) {
    newResource.upload = data; // To be saved later
  });
Run Code Online (Sandbox Code Playgroud)

此请求将发送到控制器,如下所示:

'use strict';

var _ = require('lodash');
var aws = require('aws-sdk');
var config = require('../../config/environment');
var randomString = require('../../components/randomString');

// Creates a new upload in the DB.
exports.create = function(req, res) {
  var s3 = new aws.S3();
  var folder = randomString.generate(20); // I guess I do this because when the user downloads the file it will have the original file name.
  var matches = req.body.upload.match(/data:([A-Za-z-+\/].+);base64,(.+)/);

  if (matches === null || matches.length !== 3) {
    return handleError(res, 'Invalid input string');
  }

  var uploadBody = new Buffer(matches[2], 'base64');

  var params = {
    Bucket: config.aws.bucketName,
    Key: folder + '/' + req.body.uploadName,
    Body: uploadBody,
    ACL:'public-read'
  };

  s3.putObject(params, function(err, data) {
    if (err)
      console.log(err)
    else {
      console.log("Successfully uploaded data to csk3-uploads/" + folder + '/' + req.body.uploadName);
      return res.json({
        name: req.body.uploadName,
        bucket: config.aws.bucketName,
        key: folder
      });
    }
   });
};

function handleError(res, err) {
  return res.send(500, err);
}
Run Code Online (Sandbox Code Playgroud)

服务器/组件/ randomString/index.js

'use strict';

module.exports.generate = function(textLength) {
  textLength = textLength || 10;
  var text = '';
  var possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';

  for(var i = 0; i < textLength; i++) {
    text += possible.charAt(Math.floor(Math.random() * possible.length));
  }

  return text;
};
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

server/config/environment/development.js

在此输入图像描述

server/api/upload/upload.controller.js

在此输入图像描述