web-dev-qa-db-fra.com

MEAN Stack File uploads

J'ai récemment commencé à programmer avec MEAN Stack et je suis en train de mettre en place une sorte de réseau social. J'utilise le framework MEAN.io pour le faire . Mon principal problème en ce moment est de faire en sorte que le téléchargement de fichier fonctionne, car ce que je veux, c'est recevoir le fichier du formulaire dans le contrôleur AngularJS et le transmettre avec d'autres éléments. les informations à ExpressJS afin que je puisse enfin tout envoyer à MongoDB. (Je suis en train de créer un nouveau registre d'utilisateurs).

Je ne veux pas stocker le fichier lui-même sur la base de données, mais je veux stocker un lien vers celui-ci.

J'ai cherché des dizaines de pages sur Google avec différentes requêtes de recherche, mais je n'ai rien trouvé que je puisse comprendre ou travailler. A cherché pendant des heures sans résultat. C'est pourquoi je suis venu ici.

Est-ce que quelqu'un peut m'aider avec ça?

Merci :)

EDIT: Peut-être qu'un peu du code aiderait à comprendre.

Le contrôleur MEAN.io Users Angular par défaut que j'utilise en tant que fondation a ceci:

$scope.register = function(){
        $scope.usernameError = null;
        $scope.registerError = null;
        $http.post('/register', {
            email: $scope.user.email,
            password: $scope.user.password,
            confirmPassword: $scope.user.confirmPassword,
            username: $scope.user.username,
            name: $scope.user.fullname
        })//... has a bit more code but I cut it because the post is the main thing here.
    };

Ce que je veux faire, c'est: Recevoir un fichier d'un formulaire sur ce contrôleur et le transmettre avec l'email, le mot de passe, le nom, etc., etc. et pouvoir utiliser le json sur expressjs, qui se trouve du côté serveur. . Le '/ register' est une route nodejs donc un contrôleur de serveur qui crée l'utilisateur (avec le schéma d'utilisateur) et l'envoie à MongoDB.

19
Cacos

J'ai récemment fait quelque chose comme ça. J'ai utilisé angular-file-upload . Vous souhaiterez également que node-multiparty de votre point de terminaison analyse les données du formulaire. Ensuite, vous pouvez utiliser s3 pour télécharger le fichier sur s3.

Voici quelques-uns de mes codes [modifiés].

Angular Modèle

<button>
  Upload <input type="file" ng-file-select="onFileSelect($files)">
</button>

Angular Contrôleur

$scope.onFileSelect = function(image) {
  $scope.uploadInProgress = true;
  $scope.uploadProgress = 0;

  if (angular.isArray(image)) {
    image = image[0];
  }

  $scope.upload = $upload.upload({
    url: '/api/v1/upload/image',
    method: 'POST',
    data: {
      type: 'profile'
    },
    file: image
  }).progress(function(event) {
    $scope.uploadProgress = Math.floor(event.loaded / event.total);
    $scope.$apply();
  }).success(function(data, status, headers, config) {
    AlertService.success('Photo uploaded!');
  }).error(function(err) {
    $scope.uploadInProgress = false;
    AlertService.error('Error uploading file: ' + err.message || err);
  });
};

Route

var uuid = require('uuid'); // https://github.com/defunctzombie/node-uuid
var multiparty = require('multiparty'); // https://github.com/andrewrk/node-multiparty
var s3 = require('s3'); // https://github.com/andrewrk/node-s3-client

var s3Client = s3.createClient({
  key: '<your_key>',
  secret: '<your_secret>',
  bucket: '<your_bucket>'
});

module.exports = function(app) {
  app.post('/api/v1/upload/image', 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 extension = file.path.substring(file.path.lastIndexOf('.'));
      var destPath = '/' + user.id + '/profile' + '/' + uuid.v4() + extension;

      var headers = {
        'x-amz-acl': 'public-read',
        'Content-Length': file.size,
        'Content-Type': contentType
      };
      var uploader = s3Client.upload(file.path, destPath, headers);

      uploader.on('error', function(err) {
        //TODO handle this
      });

      uploader.on('end', function(url) {
        //TODO do something with the url
        console.log('file opened:', url);
      });
    });
  });
}

J'ai changé cela à partir de mon code, donc ça ne fonctionnera peut-être pas, mais j'espère que c'est utile!

25
kentcdodds

Récemment, un nouveau paquet a été ajouté à la liste des paquets sur mean.io. C'est une beauté!

Il suffit de lancer: 

$ mean install mean-upload

Cela installe le paquet dans le dossier du noeud mais vous avez accès aux directives de vos paquets.

http://mean.io/#!/packages/53ccd40e56eac633a3eee335

Sur votre formulaire, ajoutez quelque chose comme ceci:

    <div class="form-group">
        <label class="control-label">Images</label>
        <mean-upload file-dest="'/packages/photos/'" upload-file-callback="uploadFileArticleCallback(file)"></mean-upload>
        <br>
        <ul class="list-group">
            <li ng-repeat="image in article.images" class="list-group-item">
                {{image.name}}
                <span class="glyphicon glyphicon-remove-circle pull-right" ng-click="deletePhoto(image)"></span>
            </li>
        </ul>
    </div>

Et dans votre contrôleur:

    $scope.uploadFileArticleCallback = function(file) {
      if (file.type.indexOf('image') !== -1){
          $scope.article.images.Push({
            'size': file.size,
            'type': file.type,
            'name': file.name,
            'src': file.src
          });
      }
      else{
          $scope.article.files.Push({
            'size': file.size,
            'type': file.type,
            'name': file.name,
            'src': file.src
          });
      }
    };

    $scope.deletePhoto = function(photo) {
        var index = $scope.article.images.indexOf(photo);
        $scope.article.images.splice(index, 1);
    }

Prendre plaisir!

3
jmckenney

Mean-upload est devenu obsolète et s'appelle désormais "upload". Il est géré dans - https://git.mean.io/orit/upload

0
gurpreet-SD