Wie würde man einen Datei-Upload mit Meteor behandeln?

76

Was wäre die kanonische Methode, um einen Datei-Upload mit Meteor durchzuführen?

David
quelle
2
Das ist eine vage Frage ... Fragen Sie sich, wie Sie auf der Clientseite oder auf dem Server damit umgehen sollen? In beiden Fällen stelle ich mir vor (ich habe noch nie Meteor verwendet), dass die Art und Weise, wie Dateien hochgeladen werden, so ziemlich dieselbe ist wie bei jedem anderen Server. Clientseite: Senden Sie eine POST-Anfrage an eine URL mit der Datei als Teil des Anfragetexts. Serverseitig: Warten Sie unter dieser URL auf POST-Anforderungen. Wenn eine eingeht, lesen Sie den Anforderungshauptteil und tun Sie mit den darin enthaltenen Dateien, was Sie wollen. So habe ich es im Grunde mit Node / Spring gemacht ... Wenn Sie genauer
wissen
29
Hallo JKing, du solltest dir Meteor ansehen, deshalb ist es eine interessante Frage: meteor.com
David

Antworten:

17

Derzeit scheint es keine Möglichkeit zu geben, mit dem HTTP-Server zu interagieren oder etwas im Zusammenhang mit HTTP zu tun.

Sie können nur über die von Meteor.methods bereitgestellten RPC-Methoden mit dem Server oder direkt über die bereitgestellte mongoDB-API mit mongoDB sprechen.

Raynos
quelle
Danke Raynos. Ich werde wahrscheinlich Luans Weg versuchen und den Upload mit JS-Uploadern auf S3 oder ähnliches umgehen.
David
1
@ Raynos Wissen Sie, ob die exponierte Mongo-API GridFS unterstützt? Ich kann keine Erwähnung sehen.
Steve Jalim
@stevejalim Ich weiß nicht, lesen Sie den Quellcode für die Teilmenge der Mongo-API, die es unterstützt
Raynos
1
@stevejalim Ich habe mir die Quelle angesehen, es gibt keine GridFS-Unterstützung in Minimongo (dem Paket, das sie verwenden)
bobbywilson0
3
Ich bin etwas spät zur Party hier, aber Sie können sich auch die letzten Folgen von eventedmind.com ansehen, in denen ich einen Datei-Uploader für Meteor erstelle. Die Streaming-Upload-Version des Pakets wird diese Woche veröffentlicht. Es heißt Meteor-Datei.
Am
44

Ich habe http://filepicker.io verwendet . Sie laden die Datei hoch, speichern sie in Ihrem S3 und geben Ihnen eine URL zurück, unter der sich die Datei befindet. Dann plumpse ich einfach die URL in eine DB.

  1. Wget das Filepicker-Skript in Ihren Client-Ordner.

    wget https://api.filepicker.io/v0/filepicker.js
    
  2. Fügen Sie ein Filepicker-Eingabe-Tag ein

    <input type="filepicker" id="attachment">
    
  3. Initialisieren Sie es beim Start:

    Meteor.startup( function() {
        filepicker.setKey("YOUR FILEPICKER API KEY");
        filepicker.constructWidget(document.getElementById('attachment'));
    });
    
  4. Fügen Sie einen Ereignishandler hinzu

    Templates.template.events({
        'change #attachment': function(evt){
            console.log(evt.files);
        }
    });
    
jlg_foil
quelle
Ja, filepicker.io! Total wie ein Zauber mit Heroku gearbeitet.
AbigailW
Es ist nur für 10 Tage Testversion kostenlos :(
Aladine
8
Pfff .. Ich werde nicht 100 Dollar bezahlen, nur um Dateien auf S3 hochzuladen.
Rijk
6
Echo @rijk, ich weiß nicht, warum ein kostenpflichtiger Dienst die Antwort Nummer 1 ist. Github.com/VeliovGroup/Meteor-Files oder themeteorchef.com/recipes/uploading-files-to-amazon-s3 sind beide kostenlose Lösungen, die Open implementieren Quellbibliotheken.
GFargo
1
Ich benutze edgee:slingshot, es ist großartig für große Dateien (Uploads direkt auf S3, nicht über Ihren App-Server).
Rijk
26

Für Bilder verwende ich eine ähnliche Methode wie Dario, außer dass ich die Datei nicht auf die Festplatte schreibe. Ich speichere die Daten direkt in der Datenbank als Feld im Modell. Dies funktioniert bei mir, da ich nur Browser unterstützen muss, die die HTML5-Datei-API unterstützen . Und ich brauche nur einfache Bildunterstützung.

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

Ich habe gerade eine Implementierung von Datei-Uploads mit Meteor.methods und der API von HTML5 File entwickelt. Lass mich wissen was du denkst.

Darío
quelle
3
Diese Anweisungen funktionierten also überraschend gut. Die Lösung war 10x einfacher als ich erwartet hatte und der Code funktionierte ziemlich fehlerfrei. Davon abgesehen lädt die Lösung die Bilder direkt in das lokale Dateisystem von node.j hoch. Es funktionierte zunächst hervorragend auf lokalen Entwicklungsmaschinen, hatte jedoch Probleme mit PaaS-Anbietern (Platform-as-a-Service), darunter Heroku und Nodjitsu. Das Problem besteht darin, dass bei dieser Lösung Probleme mit der Dateisystemberechtigung auftreten. Für diese Lösung ist entweder das Hosten eines eigenen Servers oder eine robustere Infrastruktur wie Amazon Elasticbeanstalk erforderlich.
AbigailW
11

Es gibt ein neues Paket: edgee: slingshot . Die Dateien werden nicht auf Ihren Meteor-Server hochgeladen, dies ist jedoch besser, da sich der Meteor-Server auf sein primäres Ziel konzentrieren kann, die Meteor-App zu bedienen, anstatt kostspielige Dateiübertragungen durchzuführen.

Stattdessen werden Dateien in Cloud-Speicherdienste hochgeladen. Derzeit werden AWS S3- und Google Cloud-Dateien unterstützt, in Zukunft werden jedoch auch Rackspace Cloud-Dateien und möglicherweise Cloudinary unterstützt.

Ihr Meteorserver fungiert lediglich als Koordinator.

Direkte indirekte VS-Uploads

Es ist auch ein sehr vielseitiges und leichtes Paket.

d_inevitable
quelle
7

Es gibt ein Atmosphärenpaket namens Router, das genau das ermöglicht.

Der beste Weg, um Datei-Uploads zu verarbeiten, ist jetzt collectionFS

Micha Roon
quelle
1
Die CFS-Gruppe von Addons ist nicht für die Produktion geeignet. Aufgrund dieser Fehler ist die Bereitstellung unserer Meteor-App kontinuierlich fehlgeschlagen, insbesondere nach dem Upgrade der App auf Meteor 1.0. Ich empfehle dringend, keine CFS-Pakete zu verwenden.
Shahriyar Imanov
7

Hier ist die beste Lösung für diese Zeit. Es verwendet collectionFS .

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

Klient:

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

Server:

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

Vorlage:

<template name="yourTemplate">
    <input class="your-upload-class" type="file">
</template>
Raz
quelle
Ich benutze deinen ganzen Code. Meteor startet normal, aber nachdem ich auf ein Element geklickt habe, wird es nicht auf den Server hochgeladen? Nichts passiert.
Erdem Güngör
@ ErdemGüngör Überprüfen Sie, ob Ihre Vorlage und Ihre Upload-Klasse in HTML mit der Vorlage übereinstimmen . yourTemplate .events und 'change .your-upload-class '. Die Funktion zum Hinzufügen von console.log bei der Ereignishandlerfunktion.
Raz
@Raz Würden Sie empfehlen, sie zu verwenden? Der Entwicklungszweig (der bei Github die Standardeinstellung zu sein scheint) sagt: "Dieser Zweig befindet sich derzeit in der aktiven Entwicklung (26.01.2015). Er weist Fehler auf und die API kann sich weiterhin ändern. Bitte helfen Sie, ihn zu testen und Fehler zu beheben." , aber noch nicht in der Produktion verwenden. " Und ihr Master-Zweig scheint ziemlich alt zu sein. Ich denke darüber nach, das Risiko einzugehen. Was schlagen Sie vor?
Ayrton Senna
1
@AyrtonSenna Wir verwenden es in der Produktion für das kleine Projekt und es funktioniert gut. Aber Sie sollten nach jedem nette Regressionstests machen meteor update. Nicht nur wegen dieses Pakets.
Raz
collectionFS ist jetzt veraltet, daher ist dies keine Lösung mehr. Wie auch immer, ich habe eine Lösung damit implementiert und musste mit vielen Fehlern umgehen, die mich letztendlich dazu veranlassten, völlig auf eine andere Option umzusteigen: Uploadcare.
Menda
4

Wenn Sie keine besonders großen Dateien benötigen oder die Dateien möglicherweise nur für einen kurzen Zeitraum speichern, funktioniert diese einfache Lösung sehr gut.

In Ihrem HTML ...

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

In Ihrer Vorlagenereigniskarte ...

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

Abonnieren Sie die Sammlung und rendern Sie in einer Vorlage einen Link ...

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

Dies ist möglicherweise nicht die robusteste oder eleganteste Lösung für große Dateien oder eine dateieintensive Anwendung. Sie eignet sich jedoch sehr gut für alle Arten von Dateiformaten, wenn Sie ein einfaches Hoch- und Herunterladen / Rendern der Dateien implementieren möchten.

Steeve Cannon
quelle
2

Sie können auf der Meteor-Roadmap sehen, dass die Funktion "Datei-Upload-Muster" für "Nach 1.0" geplant ist. Wir müssen also warten, um einen offiziellen Weg zu finden.

Derzeit ist eine der besten Möglichkeiten die Verwendung von "collectionFS" (dies ist die Entwicklungsvorschau von 0.3.x zum Zeitpunkt des Schreibens).

Oder inkfilepicker (zB filepicker.io) wie hier vorgeschlagen. Es ist einfach genug zu bedienen, obwohl dies offensichtlich eine Internetverbindung von der Benutzerseite erfordert.

Wenn Sie nur herumspielen möchten, können Sie auch die HTML5-Funktion nutzen. So etwas wie , dass .

nha
quelle
collectionFS ist sehr leistungsfähig und scheint derzeit der beste Weg zu sein.
Portforwardpodcast
2

Befolgen Sie die Anweisungen für dieses Paket, um dieselbe Aktion wie die am besten bewertete Antwort ohne die Kosten von filepicker.io auszuführen: https://github.com/Lepozepo/S3

Verwenden Sie dann den folgenden Code, um den Link zu erhalten. Schließen Sie abschließend die von SecureLink zurückgegebene URL an die Datenbank an.

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');
  }
});
Sean L.
quelle
Danke für die $("input.file_bag")[0].files. Ich hatte Mühe, einen Weg zu finden, um die zurückgegebenen Daten von einer Dateityp-Eingabe zu erhalten.
Adriano P