2012-04-11 3 views
76

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

+2

Это неопределенный вопрос ... Вы спрашиваете, как обращаться с ним на стороне клиента или на сервере? В любом случае, я полагаю (я никогда не использовал метеориту), что способ обработки загрузки файлов в значительной степени такой же, как с любым сервером. Клиентская сторона: отправьте запрос POST на URL-адрес с файлом как часть тела запроса.Серверная сторона: прослушивайте POST-запросы по этому URL-адресу, а когда приходите, читайте тело запроса и делайте все, что хотите, с любыми файлами, которые он содержит. Это в основном то, как я сделал это с помощью узла/весны ... Если вы можете быть более конкретным о том, с чем вам нужна помощь, возможно, я могу быть более полезным ... – JKing

+29

Привет, JKing, вы должны проверить Meteor, вот почему интересный вопрос: http://meteor.com/ – David

ответ

17

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

Единственное, что вы можете сделать, это поговорить с сервером по методам RPC, выставленным Meteor.methods или поговорить с mongoDB непосредственно над открытым интерфейсом mongoDB.

+0

Спасибо Raynos. Вероятно, попробуем Luan's way и обходим загрузку с загрузчиками JS на S3 или что-то в этом роде. – David

+1

@Raynos Знаете ли вы, поддерживает ли интерфейс Mongo API GridFS? Я не вижу упоминания об этом. –

+0

@stevejalim Я не знаю, прочитайте исходный код для подмножества API-интерфейса mongo, который он поддерживает – Raynos

3

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

+0

Есть [пакеты которые обрабатывают S3-загрузку для Meteor] (https://atmospherejs.com/?q=s3). –

44

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

  1. Запустите скрипт 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); 
        } 
    }); 
    
+0

Yay, filepicker.io! Полностью работал как шарм с Heroku. – AbigailW

+0

Он доступен только на 10 дней пробной версии :( – aladine

+8

Pfff .. Я не собираюсь платить за $ 100, просто чтобы загрузить файлы на S3. – Rijk

19

Я только что придумал an implementation of file uploads с использованием Meteor.methods и API HTML5 File. Дайте мне знать, что вы думаете.

+3

Итак, эти инструкции работали на удивление хорошо. Решение было в 10 раз легче, чем я ожидал, и код в значительной степени работал безупречно. При этом решение загружает изображения непосредственно в локальную файловую систему node.js. Вначале он отлично работал на локальных dev-машинах, но имел проблемы с провайдерами платформ как услуг (PaaS), включая Heroku и Nodjitsu. Проблема в том, что с этим решением возникают проблемы с разрешением файловой системы. Таким образом, это решение требует либо размещения вашего собственного сервера, либо наличия более надежной инфраструктуры, такой как Amazon Elasticbeanstalk. – AbigailW

26

Для изображений я использую метод, аналогичный Dario's, за исключением того, что я не пишу файл на диск. Я храню данные непосредственно в базе данных как поле модели. Это работает для меня, потому что мне нужно только поддерживать браузеры, поддерживающие 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); 
    } 
}); 
7

есть пакет атмосферы под названием router, который позволяет именно это.

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

+1

Группа аддонов CFS не подходит для производства - из-за них развертывание приложений Meteor не удавалось непрерывно, особенно после обновления приложения до Meteor 1.0. Я настоятельно рекомендую использовать CFS-пакеты. –

2

Вы можете увидеть на meteor roadmap, что функция «шаблон для загрузки файла» запланирован на «После 1,0». Поэтому нам нужно подождать, чтобы увидеть официальный путь.

На данный момент один из лучших способов - использовать "collectionFS" (который является предварительным предварительным просмотром 0.3.x во время написания).

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

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

+0

collectionFS очень мощный, и сейчас он кажется лучшим способом. – portforwardpodcast

3

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

В вашем 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> 

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

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

Я использую весь ваш код. Meteor начинает нормально, но после того, как я нажал на элемент, он не выведет его на сервер? Ничего не происходит. –

+0

@ ErdemGüngör Проверьте, что ** yourTemplate ** и ** your-upload-class ** в html совпадают с шаблоном. ** yourTemplate ** .events и 'change **. your-upload-class ** **. Чтобы добавить console.log в функцию обработчика события. – Raz

+0

@Raz Вы бы рекомендовали их использовать? Их ветка devel (которая, по-видимому, является дефолтом на Github), говорит: «Эта ветка находится в активной разработке прямо сейчас (2015-01-26). У нее есть ошибки, и API может продолжать изменяться. Помогите протестировать и исправить ошибки , но пока не используются в производстве ». И их главный ветвь кажется довольно старым. Я думаю о риске. Что ты предлагаешь? –

2

Чтобы выполнить те же действия, как самый upvoted ответ без стоимости 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'); 
    } 
}); 
+0

Спасибо за '$ (" input.file_bag ") [0] .files'. Я пытался найти способ получить возвращаемые данные из ввода типа файла. –

11

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

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

Ваш метеоритный сервер просто действует как координатор.

Direct VS Indirect uploads

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

Смежные вопросы