2012-04-11 11 views
76

Was wäre der kanonische Weg, um einen Datei-Upload mit Meteor zu machen?Wie würde man einen Datei-Upload mit Meteor handhaben?

+2

Das ist eine vage Frage ... Fragen Sie, wie man es auf der Clientseite oder dem Server behandelt? Wie auch immer, ich stelle mir vor (ich habe noch nie einen Meteor benutzt), dass die Art und Weise, wie mit einem Dateiupload umgegangen wird, ziemlich genau so ist wie bei jedem anderen Server. Client-Seite: Senden einer POST-Anfrage an eine URL mit der Datei als Teil des Anfragetexts.Server-Seite: Achten Sie bei dieser URL auf POST-Anfragen, und lesen Sie bei der Eingabe den Anfragetext und führen Sie mit den darin enthaltenen Dateien aus, was Sie wollen. Das ist im Grunde, wie ich es mit Knoten/Feder getan haben ... Wenn Sie spezifischere über sein können, was Sie brauchen Hilfe mit, vielleicht kann ich hilfreicher sein ... – JKing

+29

Hallo JKing, sollten Sie Meteor Check-out, das ist, warum es eine interessante Frage: http://meteor.com/ – David

Antwort

17

Es scheint derzeit keine Möglichkeit zu geben, mit dem HTTP-Server zu interagieren oder irgendetwas mit HTTP zu tun.

Die einzigen Dinge, die Sie tun können, ist mit Server über die von Meteor.methods ausgesetzt RPC-Methoden zu sprechen oder mit MongoDB direkt über die MongoDB-API ausgesetzt zu kommunizieren.

+0

Danke Raynos. Wird wahrscheinlich Luan's Art und Weise versuchen und den Upload mit JS Uploadern zu S3 oder etwas Ähnlichem umgehen. – David

+1

@Raynos Wissen Sie, ob die exponierte Mongo-API GridFS unterstützt? Ich kann es nicht erwähnen. –

+0

@stevejalim Ich weiß nicht, gehen Sie lesen den Quellcode für die Teilmenge der Mongo-API unterstützt – Raynos

3

Sie könnten versuchen, direkt auf Amazon S3 hochzuladen, ein paar Tricks mit js uploadern und so. http://aws.amazon.com/articles/1434

+0

es gibt [Pakete dass S3 Uploads für Meteor] (https://atmospherejs.com/?q=s3) jetzt behandeln. –

44

Ich verwendete http://filepicker.io. Sie laden die Datei hoch, speichern sie in Ihrem S3 und geben Ihnen eine URL zurück, wo sich die Datei befindet. Dann plumpste 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. Legen Sie eine Filepicker Eingabetag

    <input type="filepicker" id="attachment"> 
    
  3. Im Anlauf, es initialisieren:

    Meteor.startup(function() { 
        filepicker.setKey("YOUR FILEPICKER API KEY"); 
        filepicker.constructWidget(document.getElementById('attachment')); 
    }); 
    
  4. einen Event-Handler anhängen

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

Yay, filepicker.io! Ganz wie ein Zauber mit Heroku gearbeitet. – AbigailW

+0

Es ist nur kostenlos für 10 Tage Testversion :( – aladine

+8

pfff .. ich werde nicht nur $ 100 pm zahlen Dateien auf S3 hochladen. – Rijk

19

Ich bin gerade mit an implementation of file uploads mit Meteor.methods und HTML5 File API gekommen. Lass mich wissen was du denkst.

+3

Also, diese Anweisungen funktionierten überraschend gut. Die Lösung war 10x einfacher als ich erwartet hatte und der Code funktionierte einwandfrei. Davon abgesehen lädt die Lösung die Bilder direkt in das lokale Dateisystem node.js hoch. Es funktionierte zuerst auf lokalen Dev-Maschinen, hatte aber Probleme mit Platform-as-a-Service (PaaS) -Anbietern, einschließlich Heroku und Nodjitsu. Problem ist, dass bei dieser Lösung Probleme mit Dateisystemberechtigungen auftreten. Diese Lösung erfordert also entweder das Hosting Ihres eigenen Servers oder eine robustere Infrastruktur wie Amazon Elasticbeanstalk. – AbigailW

26

Für Bilder verwende ich eine ähnliche Methode wie Dario's, außer ich schreibe die Datei nicht auf die Festplatte. Ich speichere die Daten direkt in der Datenbank als ein Feld auf dem Modell. Das funktioniert für mich, weil ich nur Browser unterstützen muss, die die HTML5 File 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); 
    } 
}); 
7

gibt es eine Atmosphäre Paket namens router, die genau das ermöglicht.

eigentlich der beste Weg, das Hochladen von Dateien zu handhaben ist jetzt collectionFS

+1

Die CFS-Addonsgruppe ist nicht für die Produktion geeignet - deshalb ist die Bereitstellung unserer Meteor-App kontinuierlich gescheitert, insbesondere nach dem Upgrade der App auf Meteor 1.0. Ich empfehle dringend, CFS-Pakete zu verwenden. –

2

Sie auf den meteor roadmap sehen können, dass die Funktion „Datei-Upload-Muster“ für „After 1.0“ geplant ist. Wir müssen also auf einen offiziellen Weg warten.

Für jetzt ist eine der besten Möglichkeiten, "collectionFS" (die 0.3.x dev-Vorschau zum Zeitpunkt des Schreibens ist) zu verwenden.

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

Wenn es nur zum Spielen ist, können Sie auch die HTML5-Funktion nutzen. Etwas wie that.

+0

collectionFS ist sehr mächtig und für den Moment scheint es der beste Weg zu sein. – portforwardpodcast

3

Wenn Sie keine großen Dateien benötigen oder die Dateien nur für eine kurze Zeit speichern, funktioniert diese einfache Lösung sehr gut.

in Ihrem HTML ...

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

in Ihrer Vorlage Ereigniskarte ...

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

zur Kollektions abonnieren und in einer Vorlage einen Link machen ...

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

Während dies nicht die robusteste oder eleganteste Lösung für große Dateien oder eine dateiintensive Anwendung ist, funktioniert es gut für alle Arten von Dateiformaten, wenn Sie das einfache Hochladen und Herunterladen/Rendern der Dateien implementieren möchten.

7

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

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

Auftraggeber:

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

Ich benutze deinen ganzen Code. Meteor startet normal, aber nachdem ich ein Objekt angeklickt habe, wird es nicht auf den Server hochgeladen? Nichts passiert. –

+0

@ ErdemGüngör Überprüfen Sie, ob ** yourTemplate ** und ** your-upload-class ** in HTML mit Template identisch sind. ** yourTemplate ** .events und 'change **. your-upload-class **'. Das Hinzufügen von console.log bei der Ereignishandlerfunktion. – Raz

+0

@Raz Würden Sie die Verwendung empfehlen? Ihr Entwicklungszweig (der auf Github der Standard zu sein scheint) sagt: "Dieser Zweig befindet sich gerade in der Entwicklung (2015-01-26). Er hat Bugs und die API könnte sich weiter verändern. Bitte helft es zu testen und Bugs zu beheben , aber verwende es noch nicht in der Produktion. " Und ihr Master-Zweig scheint ziemlich alt. Ich denke daran, das Risiko einzugehen. Was schlagen Sie vor? –

2

Um die gleiche Wirkung wie die meisten upvoted Antwort ohne die Kosten für Filepicker zu erreichen. Folgen Sie den Anweisungen Für dieses Paket gilt: https://github.com/Lepozepo/S3

Um den Link zu erhalten, verwenden Sie einen ähnlichen Code wie unten. Schließen Sie abschließend die von SecureLink zurückgegebene URL in die DB.

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

Danke für das '$ (" input.file_bag ") [0] .files'. Ich hatte Mühe, eine Möglichkeit zu finden, die zurückgegebenen Daten von einer Dateitypeingabe zu erhalten. –

11

Es gibt ein neues Paket: edgee:slingshot. Es lädt die Dateien nicht auf Ihren Meteorserver hoch, aber es ist besser so, da es dem Meteorserver ermöglicht, sich auf sein primäres Ziel zu konzentrieren, die Meteor-App zu bedienen, anstatt kostspielige Dateiübertragungen zu handhaben.

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

Ihr Meteorserver dient lediglich als Koordinator.

Direct VS Indirect uploads

Es ist auch ein sehr vielseitiges und leichtes Gehäuse.