Як можна впоратися із завантаженням файлів за допомогою Meteor?


76

Яким буде канонічний спосіб обробки файлів із Meteor?


2
Це невиразне запитання ... Ви запитуєте, як з ним працювати на стороні клієнта чи сервера? У будь-якому випадку, я думаю (я ніколи не використовував метеор), що спосіб обробки завантаження файлів майже такий самий, як і на будь-якому сервері. Клієнтська сторона: надішліть запит POST на URL-адресу з файлом як частиною тіла запиту. Серверна сторона: слухайте запити POST за цією URL-адресою, а коли з’являється, читайте тіло запиту та виконуйте все, що завгодно, з будь-якими файлами, які вони містять. В основному це я зробив із node / spring ... Якщо ви можете бути більш конкретним щодо того, з чим вам потрібна допомога, можливо, я можу бути більш корисним ...
JKing,

29
Привіт JKing, ти повинен перевірити Meteor, ось чому це цікаве питання: meteor.com
Девід

Відповіді:


17

На даний момент, здається, не існує способу взаємодії з HTTP-сервером або будь-чого, що пов’язано з HTTP.

Єдине, що ви можете зробити, це поговорити з сервером за допомогою методів RPC, що виставляються Meteor.methods, або поговорити з mongoDB безпосередньо через mongoDB API.


Дякую Райносу. Можливо, спробує шлях Луана і обійде завантаження за допомогою JS-завантажувачів на S3 або щось подібне.
Девід

1
@Raynos Чи знаєте ви, чи підтримуваний API Mongo підтримує GridFS? Я не бачу згадки про це.
Steve Jalim

@stevejalim Не знаю, перейдіть читати вихідний код для підмножини монго API, який він підтримує
Райнос,

1
@stevejalim Я подивився джерело, що в minimongo немає підтримки GridFS (пакет, який вони використовують)
bobbywilson0

3
Я трохи запізнився на вечірку тут, але ви також можете переглянути останні кілька епізодів eventedmind.com, де я будую завантажувач файлів для метеору. Версія пакета для потокового завантаження вийде цього тижня. Це називається метеор-файл.
cmather

44

Я використовував http://filepicker.io . Вони завантажать файл, зберігають його у вашому S3 і повертають вам URL-адресу, де знаходиться файл. Потім я просто вкладаю URL-адресу в БД.

  1. Введіть скрипт filepicker у папку клієнта.

    wget https://api.filepicker.io/v0/filepicker.js
    
  2. Вставте тег введення файлу

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

Так, filepicker.io! Повністю працював як шарм з Героку.
AbigailW

Це безкоштовно лише на 10 днів пробного
періоду

8
Pfff .. Я не збираюся платити $ 100 вечора лише за завантаження файлів на S3.
Рейк,

6
Echo @rijk, не знаю, чому платна послуга отримала відповідь №1 . Github.com/VeliovGroup/Meteor-Files або themeteorchef.com/recipes/uploading-files-to-amazon-s3 - це безкоштовне рішення, що реалізує open джерело libs.
GFargo

1
Я використовую edgee:slingshot, він чудово підходить для великих файлів (завантажується безпосередньо на S3, а не через сервер додатків).
Рейк,

26

Для зображень я використовую метод, схожий на метод Даріо, за винятком того, що я не записую файл на диск. Я зберігаю дані безпосередньо в базі даних як поле на моделі. Це працює для мене, оскільки мені потрібно підтримувати лише браузери, які підтримують API файлів HTML5 . І мені потрібна лише проста підтримка зображень.

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

19

Я щойно придумав реалізацію завантаження файлів за допомогою Meteor.methods та API файлу HTML5. Повідомте мене, що ви думаєте.


3
Тож ці вказівки працювали напрочуд добре. Рішення було в 10 разів простішим, ніж я очікував, і код майже працював бездоганно. При цьому рішення завантажує зображення безпосередньо в локальну файлову систему node.js. Спочатку він чудово працював на локальних розробницьких машинах, але мав проблеми з провайдерами платформи як послуги (PaaS), включаючи Heroku та Nodjitsu. Проблема полягає в тому, що у цього рішення є проблеми з дозволом на файлову систему. Отже, для цього рішення потрібно або розміщення власного сервера, або наявність більш надійної інфраструктури, наприклад Amazon Elasticbeanstalk.
AbigailW

11

З'явився новий пакет: edgee: slingshot . Він не завантажує файли на ваш метеорний сервер, але це краще, оскільки він дозволяє метеорному серверу зосередитись на своїй головній меті - обслуговувати метеорну програму, а не обробляти дорогі передачі файлів.

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

Ваш метеорний сервер виконує лише функцію координатора.

Пряме VS непряме завантаження

Це також дуже універсальний та легкий пакет.


7

є пакет атмосфери під назвою маршрутизатор, який дозволяє саме це.

насправді, найкращим способом обробки завантажень файлів є зараз collectionFS


1
Група аддонів CFS не підходить для виробництва - через них розгортання нашої програми Meteor постійно зазнавало невдач, особливо після оновлення програми до Meteor 1.0. Я настійно не рекомендую використовувати пакети CFS.
Шахріяр Іманов

7

Ось найкраще рішення на цей час. Він використовує 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>

Я використовую весь ваш код. Метеор запускається нормально, але після того, як я натиснув елемент, він не завантажує його на сервер? Нічого не трапляється.
Erdem Güngör

@ ErdemGüngör Переконайтеся, що ваш шаблон і клас завантаження в html однакові з шаблоном. yourTemplate .events та 'change .your-upload-class '. Додавання console.log у функції обробника подій.
Raz

@Raz Чи не рекомендували б ви їх використовувати? Їх гілка розробника (яка, як видається, за замовчуванням на Github) каже: "Ця гілка зараз активно розробляється (26.01.2015). У ній є помилки, і API може продовжувати змінюватися. Будь ласка, допоможіть протестувати та виправити помилки , але поки не використовуйте у виробництві ". І їхня гілка Майстра здається досить старою. Я думаю ризикнути. Що ти пропонуєш?
Айртон Сенна

1
@AyrtonSenna Ми використовуємо його у виробництві для невеликого проекту, і він працює добре. Але слід робити приємні регресійні тести після кожного meteor update. Не тільки завдяки цьому пакету.
Raz

collectionFS тепер застарілий, тому це вже не рішення. У будь-якому випадку, я реалізував з ним рішення, і мені доводилося обробляти багато помилок, які зрештою змусили мене повністю змінити інший варіант: Uploadcare.
Менда

4

Якщо вам не потрібні значно великі файли або, можливо, зберігання файлів протягом короткого періоду часу, тоді це просте рішення працює дуже добре.

У вашому 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>

Хоча це може бути не найнадійнішим або елегантним рішенням для великих файлів або інтенсивного використання файлів, воно дуже добре працює для всіх типів форматів файлів, якщо ви хочете здійснити просте завантаження та завантаження / візуалізацію файлів.



2

Ви можете бачити на дорожній карті метеору що функція "Шаблон завантаження файлів" запланована на "Після 1.0". Тож ми повинні почекати, щоб побачити офіційний шлях.

Наразі одним із найкращих способів є використання "collectionFS" (що становить 0,3.x попередній перегляд розробника на момент написання).

Або inkfilepicker (наприклад, filepicker.io), як пропонується тут. Він досить простий у використанні, хоча для цього, очевидно, потрібне і підключення до Інтернету з боку користувача.

Якщо це просто пограти, ви також можете скористатися функцією html5. Щось подібне , що .


collectionFS дуже потужний, і зараз він здається найкращим способом.
portforwardpodcast


2

Щоб виконати ту саму дію, що і найголосніша відповідь, без вартості 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');
  }
});

Дякую за $("input.file_bag")[0].files. Я намагався знайти спосіб отримати повернені дані із вводу типу файлу.
Адріано П
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.