2014-10-19 4 views
8

Ich habe eine Meteor App und ich bin daran interessiert, Bild-Upload auf die einfachste Weise zu funktionieren.Meteor: Hochladen eines Bildes und Speichern in der Datenbank als base64 string

Die einfachste Art, die ich mir vorstellen kann, besteht darin, das Bild irgendwie in eine Base64-Zeichenfolge auf dem Client umzuwandeln und es als String in der Datenbank zu speichern.

Wie ist es möglich, ein Bild auf dem Benutzer-Dateisystem in eine Base64-Zeichenfolge zu konvertieren und dann in der Datenbank zu speichern?

+0

Wie über das Speichern des Abbilds auf dem Server. Kann jemand einen Arbeitscode posten? Ich habe versucht, die ImageCollection.write-Funktion zu verwenden und ist fehlgeschlagen. Vielen Dank ! –

Antwort

8

können Sie verwenden, um ein HTML5-Eingabedatei:

HTML

<template name="fileUpload"> 
    <form> 
    <input type="file" name="imageFile"> 
    <button type="submit" disabled={{submitDisabled}}> 
     Submit 
    </button> 
    </form> 
</template> 

dann auf das Änderungsereignis hören und ein FileReader verwenden, um die lokale Datei als base64-Daten-URL zu lesen, die wir gehen zu speichern in einem reaktiven var:

Template.fileUpload.created=function(){ 
    this.dataUrl=new ReactiveVar(); 
}; 

Template.fileUpload.events({ 
    "change input[type='file']":function(event,template){ 
    var files=event.target.files; 
    if(files.length===0){ 
     return; 
    } 
    var file=files[0]; 
    // 
    var fileReader=new FileReader(); 
    fileReader.onload=function(event){ 
     var dataUrl=event.target.result; 
     template.dataUrl.set(dataUrl); 
    }); 
    fileReader.readAsDataURL(file); 
    } 
}); 

Dann haben wir den reaktiven var Wert verwenden können, ermöglichen/nicht zulassen Formularübermittlung und den Wert an den Server senden:

Template.fileUpload.helpers({ 
    submitDisabled:function(){ 
    return Template.instance().dataUrl.get(); 
    } 
}); 

Template.fileUpload.events({ 
    "submit":function(event,template){ 
    event.preventDefault(); 
    // 
    Meteor.call("uploadImage",template.dataUrl.get()); 
    } 
}); 

Sie müssen eine Server-Methode definieren, die die dataUrl bis zu einem gewissen Sammlung Feldwert speichert, was dataUrl cool ist, dass man sie direkt als Image-Tag src verwenden kann.

Beachten Sie, dass diese Lösung sehr unskalierbar ist, da die Bilddaten nicht zwischengespeichert werden können und die regelmäßige Kommunikation der App-Datenbank (die nur textähnliche Werte enthalten sollte) verschmutzen wird.

Sie können die base64-Daten von dataUrl abrufen und in Google Cloud Storage oder Amazon S3 hochladen und die Dateien hinter einem CDN bereitstellen.

Sie könnten auch Dienste verwenden, die all diese Sachen für Sie tun, wie Uploadcare oder Filepicker.

EDIT:

Diese Lösung ist einfach zu implementieren, aber mit dem Hauptnachteil kommt, dass großen base64-Strings aus mongodb holt Ihre App von Abrufen andere Daten verlangsamen, DDP-Kommunikation wird immer leben und nicht im Moment cachable so Ihre App lädt immer wieder Bilddaten vom Server herunter.

Sie würden dataUrl nicht an Amazon speichern, Sie würden das Bild direkt speichern und es würde von Ihrer App mit einer Amazon-URL mit einer HTTP-Anfrage abgerufen werden.

Beim Hochladen von Dateien haben Sie zwei Möglichkeiten: Sie können sie direkt vom Client mit bestimmten JavaScript-Browser-APIs hochladen oder sie in Node.js (NPM-Module) APIs auf dem Server hochladen.

Wenn Sie vom Server hochladen möchten (was normalerweise einfacher ist, weil Sie nicht benötigen, dass die Benutzer Ihrer Apps sich gegen Dienste von Drittanbietern authentifizieren, fungiert nur Ihr Server als vertrauenswürdiger Client für die Kommunikation Mit Amazon API) können Sie dann die Daten, die ein Benutzer hochladen möchte, über einen Methodenaufruf mit einem dataUrl als Argument senden.

Wenn Sie nicht in all diese Sachen tauchen wollen, sollten Sie uploadcare oder filepicker verwenden, aber denken Sie daran, dass diese Dienste kostenpflichtig sind (wie Amazon S3 BTW).

+0

ah danke für deine Antwort und den Kommentar zur Skalierung. Ich wusste nicht, der Grund, warum ich Base64 verwenden wollte, ist, weil ich nicht mit dem Hochladen einer Datei und dem Speichern in Amazon und dem Abrufen eines Links zu der Datei arbeiten müsste. Ich dachte, das wäre einfach, da ich das Bild wie alle Daten behandeln und die Seite mit img src füllen kann. Also denke ich, deine Empfehlung, die Saite auf Amazon S3 zu speichern, würde funktionieren. Es wäre immer noch einfacher als die eigentliche Bilddatei zu übertragen. Ich frage mich, wo ich String-Werte speichern und abrufen kann, fast kostenlos und schnell? – nearpoint

+0

Dies würde keinen Sinn machen, DataUrl auf Amazon S3 zu speichern, siehe meine Bearbeitung. – saimeunt

+0

Wie bekomme ich mehrere Dateien und ihre DataUrl in base64? – Viddesh

2

Nicht sicher, ob dies der beste Weg ist, aber Sie können dies mit einem Datei-Reader leicht tun. Im Template-Ereignishandler, in dem Sie den Dateiinhalt erhalten, können Sie die Datei an den Leser übergeben und eine Base64-Zeichenfolge zurückgeben. Zum Beispiel so etwas wie:

Template.example.events({ 
    'submit form': function (event, template) { 
    var reader = new FileReader(); 
    var file = template.find('#fileUpload').files[0]; // get the file 

    reader.onload = function (event) { 
     // event.target.result is the base64 string 
    } 
    reader.readAsDataURL(file); 
    } 
}); 
Verwandte Themen