2014-10-19 8 views
8

Ho un'applicazione Meteor e sono interessato a ottenere il caricamento delle immagini per funzionare nel modo più semplice possibile.Meteor: caricamento di un'immagine e salvataggio nel database come stringa base64

Il modo più semplice che riesco a fare è convertire in qualche modo l'immagine in una stringa base64 sul client e salvarla nel database come stringa.

Come è possibile convertire un'immagine sul filesystem dell'utente in una stringa base64 e quindi salvarla nel database?

+0

Che ne dici di salvare l'immagine sul server. qualcuno può pubblicare un codice funzionante? Stavo cercando di utilizzare la funzione ImageCollection.write e non sono riuscito. Grazie ! –

risposta

8

È possibile utilizzare un file di input HTML5:

HTML

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

poi ascoltare l'evento di modifica e utilizzare un FileReader per leggere il file locale come un URL di dati Base64 che stiamo andando a conservare in un var reattivo:

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

Poi possiamo usare il valore var reattivi per consentire/non consentire scheda di iscrizione e inviare il valore al server:

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

Sarà necessario definire un metodo di server che salva il dataUrl ad un valore di campo di raccolta, ciò che è cool dataUrl s è che si possono usare direttamente come un tag immagine src.

Si noti che questa soluzione è altamente non scalabile poiché i dati dell'immagine non sono intercambiabili e inquinano le comunicazioni regolari del database dell'app (che dovrebbero contenere solo valori di tipo testo).

È possibile recuperare i dati di base64 dallo dataUrl e caricarlo su Google Cloud Storage o Amazon S3 e servire i file dietro una CDN.

È inoltre possibile utilizzare servizi che fanno tutto questo per voi come uploadcare o filepicker.

EDIT:

Questa soluzione è facile da implementare, ma viene fornito con il principale svantaggio che il recupero di grandi dimensioni stringhe base64 da mongodb rallenterà la vostra applicazione da andare a prendere altri dati, comunicazioni DDP sono sempre sotto tensione e non inserirle nella cache in questo momento così la tua app scaricherà sempre di nuovo i dati delle immagini dal server.

Non si salverà dataUrl su Amazon, si salverà l'immagine direttamente e verrà recuperata dall'app utilizzando un URL Amazon con una richiesta HTTP intercambiabile.

Sono disponibili due opzioni per il caricamento di file: è possibile caricarle direttamente dal client utilizzando specifiche API del browser javascript oppure caricarle tramite le API Node.js (moduli NPM) nel server.

Nel caso in cui si desideri caricare dal server (che di solito è più semplice perché non è necessario richiedere che gli utenti delle app si autenticano da servizi di terze parti, solo il server fungerà da client fidato per comunicare con Amazon API), quindi è possibile inviare i dati che un utente desidera caricare tramite una chiamata di metodo con un argomento dataUrl.

Se non vuoi immergerti in tutto questo, considera l'utilizzo di uploadcare o filepicker, ma tieni presente che si tratta di servizi a pagamento (come Amazon S3 BTW).

+0

ah grazie per la tua risposta e il commento sul ridimensionamento. Non lo sapevo, la ragione per cui volevo usare base64 è perché non avrei dovuto occuparmi di caricare un file e salvarlo su Amazon e recuperare il link al file. Ho pensato che sarebbe stato facile dato che posso trattare l'immagine come qualsiasi dato e popolare la pagina con img src. Quindi immagino che la tua raccomandazione di archiviare la stringa su Amazon s3 o qualcosa funzionerebbe. Sarebbe ancora più semplice del trasferimento del file immagine reale. Mi chiedo dove posso archiviare e recuperare i valori stringa, quasi gratis e veloce? – nearpoint

+0

Non avrebbe senso memorizzare dataUrl su Amazon S3, vedere la mia modifica. – saimeunt

+0

Come ottenere più file e il suo dataUrl in base64? – Viddesh

2

Non sicuro se questo è il modo migliore, ma è possibile farlo facilmente con un lettore di file. Nel gestore di eventi Modello in cui si ottiene il contenuto del file, è possibile passare il file al lettore e recuperare una stringa base64. Ad esempio, qualcosa di simile:

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