web-dev-qa-db-fra.com

Comment gérer un téléchargement de fichier avec Meteor?

Quelle serait la manière canonique de gérer un téléchargement de fichier avec Meteor?

76
David

Actuellement, il ne semble pas y avoir de moyen d'interagir avec le serveur HTTP ou de faire quoi que ce soit en rapport avec HTTP.

La seule chose que vous pouvez faire est de parler au serveur via les méthodes RPC exposées par Meteor.methods ou de parler directement à mongoDB via l'API mongoDB exposée.

17
Raynos

J'ai utilisé http://filepicker.io . Ils vont télécharger le fichier, le stocker dans votre S3 et vous retourner une URL où se trouve le fichier. Ensuite, je plop juste l'URL dans une base de données.

  1. Mettez le script filepicker dans votre dossier client.

    wget https://api.filepicker.io/v0/filepicker.js
    
  2. Insérer une balise d'entrée Filepicker

    <input type="filepicker" id="attachment">
    
  3. Au démarrage, initialisez-le:

    Meteor.startup( function() {
        filepicker.setKey("YOUR FILEPICKER API KEY");
        filepicker.constructWidget(document.getElementById('attachment'));
    });
    
  4. Attacher un gestionnaire d'événements

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

Pour les images, j'utilise une méthode similaire à Dario's sauf que je n'écris pas le fichier sur le disque. Je stocke les données directement dans la base de données en tant que champ sur le modèle. Cela fonctionne pour moi car je dois uniquement prendre en charge les navigateurs prenant en charge HTML5 File API . Et je n'ai besoin que d'un support d'image simple.

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);
  }
});
26
Harry Love

Je viens de trouver ne implémentation de téléchargements de fichiers en utilisant Meteor.methods et l'API HTML5 File. Laissez-moi savoir ce que vous pensez.

19
Darío

Il y a un nouveau package: edgee: slingshot . Il ne télécharge pas les fichiers sur votre serveur de météores, mais c'est mieux ainsi car il permet au serveur de météores de se concentrer sur son objectif principal de servir l'application de météores au lieu de gérer des transferts de fichiers coûteux.

Au lieu de cela, il télécharge des fichiers vers des services de stockage cloud. Actuellement, il prend en charge AWS S3 et Google Cloud Files, mais il prendra également en charge Rackspace Cloud Files et peut-être Cloudinary à l'avenir.

Votre serveur de météores agit simplement comme un coordinateur.

Direct VS Indirect uploads

C'est également un ensemble très polyvalent et léger.

11
d_inevitable

Voici la meilleure solution pour cette fois. Il utilise collectionFS .

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

Client:

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

Serveur:

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

Modèle:

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

il y a un paquet d'ambiance appelé routeur qui permet cela.

en fait, la meilleure façon de gérer les téléchargements de fichiers est maintenant collectionFS

7
Micha Roon

Si vous n'avez pas besoin de fichiers de grande taille ou si vous ne stockez les fichiers que pendant une courte période, cette solution simple fonctionne très bien.

Dans votre html ...

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

Dans votre modèle de carte d'événements ...

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

Abonnez-vous à la collection et dans un modèle rendre un lien ...

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

Bien que ce ne soit pas la solution la plus robuste ou élégante pour les fichiers volumineux ou une application gourmande en fichiers, elle fonctionne très bien pour tous les types de formats de fichiers si vous souhaitez mettre en œuvre un simple téléchargement et téléchargement/rendu des fichiers.

3
Steeve Cannon

Vous pouvez essayer de télécharger directement sur Amazon S3, en faisant quelques astuces avec les téléchargeurs js et d'autres choses. http://aws.Amazon.com/articles/1434

3
Luan

Vous pouvez voir sur la feuille de route des météores que la fonction "Modèle de téléchargement de fichier" est prévue pour "Après 1.0". Il faut donc attendre de voir une voie officielle.

Pour l'instant, l'un des meilleurs moyens consiste à utiliser "collectionFS" (qui est un aperçu de 0,3.x dev au moment de l'écriture).

Ou inkfilepicker (ex. Filepicker.io) comme suggéré ici. Il est assez facile à utiliser, bien que cela nécessite évidemment une connexion Internet du côté de l'utilisateur.

Si c'est juste pour jouer, vous pourriez aussi bien profiter de la fonctionnalité html5. Quelque chose comme que .

2
nha

Pour accomplir la même action que la réponse la plus votée sans le coût de filepicker.io, suivez les instructions de ce package: https://github.com/Lepozepo/S

Ensuite, pour obtenir le lien, utilisez un code similaire à celui ci-dessous. Enfin, branchez l'URL renvoyée par secureLink dans la base de données.

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');
  }
});
2
Sean L

voici encore une autre solution:

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

Celui-ci utilise la solution de téléchargement de Blueimp qui prend en charge les téléchargements en bloc, les barres de progression et plus encore.

2
tomitrescak