Загрузка файлов в файл MEAN

18

Недавно я начал программирование с помощью MEAN Stack, и в настоящее время я реализую какую-то социальную сеть. Для этого используется среда MEAN.io. Моя главная проблема прямо сейчас заключается в том, чтобы загрузить файл на работу, потому что я хочу получить файл из формы в контроллер AngularJS и передать его вместе с дополнительной информацией в ExpressJS, чтобы я мог, наконец, отправить все в MongoDB. (Я создаю регистрационную новую пользовательскую форму).

Я не хочу хранить сам файл в базе данных, но хочу сохранить ссылку на него.

Я искал десятки страниц в Google с разными поисковыми запросами, но я не мог найти ничего, что мог бы понять или сработать. Был поиск часов без каких-либо результатов. Вот почему я пришел сюда.

Может ли кто-нибудь помочь мне с этим?

Спасибо:)

EDIT: Может быть, немного кода поможет понять.

По умолчанию MEAN.io Users Angular controller, который я использую в качестве основы, имеет следующее:

$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.
    };

Что я хочу сделать: Получите файл из формы на этот контроллер и передайте его вместе с электронной почтой, паролем, именем и т. Д. И т. Д. И сможете использовать json on expressjs, который находится на стороне сервера. «/ Register» - это маршрут nodejs, поэтому серверный контроллер создает пользователя (с пользовательской схемой) и отправляет его в MongoDB.

    
задан Cacos 08.04.2014 в 17:31
источник
  • Средняя загрузка была устаревшей и теперь называется «upload». Он управляется in-git.mean.io/orit/upload, но даже это не обновлялось через несколько месяцев ... –  Tony J. Fader 11.03.2016 в 20:08

4 ответа

25

Недавно я сделал что-то подобное. Я использовал загрузку углового файла . Вы также захотите многоуровневый узел для вашей конечной точки для анализа данных формы. Затем вы можете использовать s3 для загрузки файла на s3.

Вот некоторые из моих [отредактированных] кодов.

Угловой шаблон

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

Угловой контроллер

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

Маршрут

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

Я изменил это из своего кода, поэтому он может не работать из коробки, но, надеюсь, это полезно!

    
ответ дан kentcdodds 14.04.2014 в 19:13
источник
  • Привет, спасибо за ваш ответ! Мне удалось заставить его работать в конце концов! У меня появилась только одна проблема: изображение загружается, прежде чем я отправлю форму, но я думаю, что мне удастся сделать работу по назначению. Я также использовал загрузку с угловым файлом, но (немой я) не проверял консоль Chrome на наличие ошибок, я отсутствовал с некоторым родителем, и он не работал (конечно!). Но мне удалось заставить его работать! Но спасибо за ваш ответ! –  Cacos 15.04.2014 в 11:01
  • @ Какос, я рад, что вы его работали. Пожалуйста, примите ответ, так что фиолетовый поиск этого из Google может найти ответ более легко. –  kentcdodds 15.04.2014 в 14:58
  • Кроме того, в качестве подсказки. Вероятно, вы всегда должны открывать консоль при разработке ... Довольно сложно развиваться без нее. Как вы обнаружили ... :-) –  kentcdodds 15.04.2014 в 15:00
  • Выполнено, и да, теперь я работаю с консолью, которая всегда открыта! Ошибки новичков: P –  Cacos 16.04.2014 в 10:50
  • Я пробовал следовать вашим советам и другим аналогичным учебникам, но я продолжаю получать сообщение об ошибке. 'Var file.files [0]' сбой моего приложения, дающего сообщение, не может читать 0 из неопределенного. Есть ли у вас какие-либо идеи, какова моя проблема? –  Charlie Tupman 27.04.2015 в 23:31
3

Недавно новый пакет был добавлен в список пакетов на mean.io. Это красота!

Просто запустите:

$ mean install mean-upload

Это устанавливает пакет в папку узла, но у вас есть доступ к директивам в ваших пакетах.

Ссылка

В форме формы добавьте что-то вроде этого:

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

И в вашем контроллере:

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

Наслаждайтесь!

    
ответ дан jmckenney 05.08.2014 в 20:45
источник
0

Средняя загрузка была устарела и теперь называется «upload». Он управляется в Ссылка

    
ответ дан gurpreet-SD 21.06.2016 в 13:53
источник
0

Я знаю, что этот пост старый. Я столкнулся с этим, и у @kentcdodds был ответ, который мне очень понравился, но библиотеки, которые он использовал, теперь устарели, и я не мог заставить их работать. Поэтому после некоторых исследований у меня появилось более новое подобное решение, которое я хочу разделить.

HTML с использованием ng-upload

<form >
    <div style="margin-bottom: 15px;">
        <button type="file" name="file" id="file" ngf-select="uploadFiles($file, $invalidFiles)" accept="image/*" ngf-max-height="1000" ngf-max-size="1MB">Select File</button>
    </div>
</form>

ВКЛЮЧИТЬ модуль ng-upload

загрузите его, ссылайтесь на файлы и включите модуль

var app = angular.module('app', ['ngFileUpload']);

это даст вам доступ к службе Upload .

Код контроллера

$scope.uploadFiles = function(file, errFiles) {
    $scope.f = file;
    $scope.errFile = errFiles && errFiles[0];
    if (file) {
        file.upload = Upload.upload({
            url: 'you-api-endpoint',
            data: {file: file}
        });

        //put promise and event watchers here if wanted
    }   
};

Код NODE api

Весь приведенный ниже код находится в отдельном файле route , который является required в моем главном файле server.js.

require('./app/app-routes.js')(app, _);

var fs = require('fs');
var uuid = require('uuid');
var s3 = require('s3fs'); // https://github.com/RiptideElements/s3fs
var s3Impl = new s3('bucketname', {
    accessKeyId: '<your access key id>',
    secretAccessKey: '< your secret access key >'
});

var multiparty = require('connect-multiparty');
var multipartyMiddleware = multiparty();

module.exports = function(app, _) {
    app.use(multipartyMiddleware);


    app.post('/your-api-endpoint',function(req, res){

    var file = req.files.file; // multiparty is what allows the file to to be accessed in the req
    var stream = fs.createReadStream(file.path);
    var extension = file.path.substring(file.path.lastIndexOf('.'));
    var destPath = '/' + req.user._id + '/avatar/' +  uuid.v4() + extension;
    var base = 'https://you-bucket-url';
    return s3Impl.writeFile(destPath, stream, {ContentType: file.type}).then(function(one){
        fs.unlink(file.path);
        res.send(base + destPath); 
    });
});

Все, что я пытался сделать, это загрузить уникальный аватар для пользователя. Надеюсь, это поможет!

    
ответ дан TravRob 18.10.2016 в 07:14
источник