Как можно обрабатывать загрузку файлов с помощью Meteor?


каков был бы канонический способ обработки загрузки файлов с помощью Meteor?

12 76

12 ответов:

в настоящее время, похоже, нет способа взаимодействовать с HTTP-сервером или делать что-либо, связанное с HTTP.

единственное, что вы можете сделать, это поговорить с сервером по методам RPC, выставленным Meteor.методы или поговорите с mongoDB непосредственно через API mongoDB.

я использовал http://filepicker.io. они загрузят файл, сохранят его в вашем S3 и вернут вам URL-адрес, где находится файл. Затем я просто плюхаю url в БД.

  1. Wget сценарий filepicker в папку клиента.

    wget https://api.filepicker.io/v0/filepicker.js
    
  2. вставьте входной тег filepicker

    <input type="filepicker" id="attachment">
    
  3. в запуске инициализируйте его:

    Meteor.startup( function() {
        filepicker.setKey("YOUR FILEPICKER API KEY");
        filepicker.constructWidget(document.getElementById('attachment'));
    });
    
  4. прикрепить событие обработчик

    Templates.template.events({
        'change #attachment': function(evt){
            console.log(evt.files);
        }
    });
    

для изображений я использую метод, аналогичный Дарио за исключением того, что я не записываю файл на диск. Я храню данные непосредственно в базе данных в виде поля на модели. Это работает для меня, потому что мне нужно только поддерживать браузеры, которые поддерживают HTML5 File API. И мне нужна только простая поддержка изображений.

Template.myForm.events({
  'submit form': function(e, template) {
    e.preventDefault();
    var file = template.find('input type=["file"]').files[0];
    var reader = new FileReader();
    reader.onload = function(e) {
      // Add it to your model
      model.update(id, { $set: { src: e.target.result }});

      // Update an image on the page with the data
      $(template.find('img')).attr('src', e.target.result);
    }
    reader.readAsDataURL(file);
  }
});

Я только что придумал реализация загрузки файлов С помощью Метеор.методы и API файла HTML5. Дай мне знать, что ты думаешь.

есть новый пакет: edgee: slingshot. Он не загружает файлы на ваш сервер meteor, но это лучше, так как он позволяет серверу meteor сосредоточиться на своей основной цели обслуживания приложения meteor вместо обработки дорогостоящих передач файлов.

вместо этого он загружает файлы в облачные службы хранения. В настоящее время он поддерживает AWS S3 и Google Cloud Files, но он также будет поддерживать облачные файлы Rackspace и, возможно, Cloudinary в будущее.

ваш "Метеор" сервер выступает лишь в качестве координатора.

Direct VS Indirect uploads

Это также очень универсальный и легкий пакет.

есть пакет атмосферы под названием маршрутизатор что позволяет именно это.

на самом деле, лучший способ обработки загрузки файлов теперь collectionFS

вот лучшее решение для этого времени. Он использует collectionFS.

meteor add cfs:standard-packages
meteor add cfs:filesystem

клиент:

Template.yourTemplate.events({
    'change .your-upload-class': function(event, template) {
        FS.Utility.eachFile(event, function(file) {
            var yourFile = new FS.File(file);
            yourFile.creatorId = Meteor.userId(); // add custom data
            YourFileCollection.insert(yourFile, function (err, fileObj) {
                if (!err) {
                   // do callback stuff
                }
            });
        });
    }
});

сервер:

YourFileCollection = new FS.Collection("yourFileCollection", {
    stores: [new FS.Store.FileSystem("yourFileCollection", {path: "~/meteor_uploads"})]
});
YourFileCollection.allow({
    insert: function (userId, doc) {
        return !!userId;
    },
    update: function (userId, doc) {
        return doc.creatorId == userId
    },
    download: function (userId, doc) {
        return doc.creatorId == userId
    }
});

шаблон:

<template name="yourTemplate">
    <input class="your-upload-class" type="file">
</template>

вы можете попробовать загрузить непосредственно на amazon S3, делая некоторые трюки с загрузчиками js и прочее. http://aws.amazon.com/articles/1434

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

в вашем html...

<input id="files" type="file" />

в вашем шаблоне карты событий...

Template.template.events({
  'submit': function(event, template){
    event.preventDefault();
    if (window.File && window.FileReader && window.FileList && window.Blob) {
      _.each(template.find('#files').files, function(file) {
        if(file.size > 1){
          var reader = new FileReader();
          reader.onload = function(e) {
            Collection.insert({
              name: file.name,
              type: file.type,
              dataUrl: reader.result
            });
          }
          reader.readAsDataURL(file);
        }
      });
    }
  }
});

подпишитесь на коллекцию и в шаблоне отобразите ссылку...

<a href="{{dataUrl}}" target="_blank">{{name}}</a>

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

вы можете видеть на Метеор "дорожной карты" что функция " шаблон загрузки файла "запланирована на"после 1.0". Поэтому мы должны подождать, чтобы увидеть официальный путь.

на данный момент, один из лучших способов-использовать "collectionFS" (что составляет 0,3.предварительный просмотр X dev во время написания).

или inkfilepicker (ex. filepicker.io) как предлагается здесь. Он достаточно прост в использовании, хотя для этого, очевидно, требуется и подключение к Интернету со стороны пользовательская сторона.

Если это просто играть вокруг, вы могли бы также воспользоваться функцией html5. Что-то вроде это.

вот еще одно решение:

https://doctorllama.wordpress.com/2014/11/06/meteor-upload-package-with-jquery-file-upload/

этот использует решение для загрузки Blueimp, которое поддерживает фрагментированные загрузки, индикаторы выполнения и многое другое.

чтобы выполнить то же действие, что и самый популярный ответ без затрат filepicker.io, следуйте инструкциям для этого пакета:https://github.com/Lepozepo/S3

затем, чтобы получить ссылку, используйте код, аналогичный приведенному ниже. Наконец, подключите url, возвращенный secureLink в БД.

Template.YourTemplate.events({
  "click button.upload": function() {
    var files = $("input.file_bag")[0].files;
    S3.upload(files, "/subfolder", function(e,r) {
      console.log(r);
      Session.set('secureLink', r.secure_url);
    })
  }
});
Template.YourTemplate.helpers({
  "files": function() {
    return S3.collection.find();
  },

  "secureLink": function() {
    return Session.get('secureLink');
  }
});