2014-10-19 10 views
8

Mam aplikację Meteor i jestem zainteresowany przesyłaniem obrazów do pracy w najprostszy z możliwych sposobów.Meteor: Załadowanie obrazu i zapisanie do bazy danych jako łańcuch base64

Najprostszy sposób, w jaki mogę wymyślić, to jakoś przekonwertować obraz na ciąg base64 na kliencie i zapisać go w bazie danych jako ciąg.

Jak można przekształcić obraz w systemie plików użytkownika na ciąg base64, a następnie zapisać go w bazie danych?

+0

Co powiecie na zapisanie obrazu na serwerze. Czy ktoś może opublikować działający kod? Próbowałem użyć funkcji ImageCollection.write i nie powiodło się. Dzięki ! –

Odpowiedz

8

Można używać HTML5 plik wejściowy:

HTML

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

następnie słuchać przypadku zmian i użyć FileReader odczytać pliku lokalnego jako adres URL danych base64, że mamy zamiar przechowywać w reaktywnym 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); 
    } 
}); 

Wtedy możemy skorzystać z reaktywną wartość var ​​do akceptowania/odrzucania przesyłanie formularza i wysłać do serwera wartość:

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

Musisz określić metodę serwera, który zapisuje dataUrl do pewnego zbierania wartości pola, co jest fajnego dataUrl s jest to, że można ich używać bezpośrednio jako znacznik obrazu src.

Należy zauważyć, że to rozwiązanie jest wysoce nie skalowalne, ponieważ dane obrazu nie będą buforowane i będą zanieczyszczać regularną komunikację bazy danych aplikacji (która powinna zawierać tylko wartości podobne do tekstu).

Możesz pobrać dane base64 z dataUrl i przesłać je do Google Cloud Storage lub Amazon S3 i podać pliki znajdujące się za CDN.

Można również użyć usług, które wykonują wszystkie te czynności dla Ciebie, takich jak uploadcare lub filepicker.

EDIT:

To rozwiązanie jest łatwe do wdrożenia, ale pochodzi z głównej wadę, że pobieranie dużych ciągów base64 z MongoDB będzie spowolnić swoją aplikację z pobierania innych danych, komunikacji DDP zawsze żyć i nie cachable w tej chwili tak Twoja aplikacja zawsze pobierze ponownie dane obrazu z serwera.

Nie można zapisać dataUrl s do Amazon, należy zapisać obraz bezpośrednio, a zostanie ono pobrane przez aplikację przy użyciu adresu URL Amazon z możliwym do buforowania żądaniem HTTP.

Masz dwie możliwości, jeśli chodzi o przesyłanie plików: możesz je przesłać bezpośrednio z klienta za pomocą konkretnych interfejsów API przeglądarki JavaScript lub możesz przesłać je w interfejsie API Node.js (moduły NPM) na serwerze.

Jeśli chcesz przesłać z serwera (co jest zwykle prostsze, ponieważ nie musisz wymagać, aby użytkownicy twoich aplikacji uwierzytelniali się w stosunku do usług stron trzecich, tylko twój serwer będzie działać jako zaufany klient do komunikacji z Amazon API), możesz wysyłać dane, które użytkownik chce przesłać poprzez wywołanie metody z argumentem dataUrl.

Jeśli nie chcesz zagłębić się w te wszystkie rzeczy, rozważ użycie funkcji uploadcare lub filepicker, ale pamiętaj, że są to płatne usługi (tak jak Amazon S3 BTW).

+0

ah dzięki za odpowiedź i komentarz na temat skalowania. Nie wiedziałem, powodem, dla którego chciałem użyć base64 jest to, że nie musiałbym zajmować się przesyłaniem pliku i zapisywaniem go do Amazona oraz uzyskiwaniem odnośnika do pliku. Pomyślałem, że będzie to łatwe, ponieważ mogę traktować obraz tak samo jak wszelkie dane i zapełniać go stroną przy pomocy img src. Zgaduję więc, że twoja rekomendacja przechowywania sznurka na amazon s3 lub coś by działało. Byłoby to jeszcze łatwiejsze niż przeniesienie rzeczywistego pliku obrazu. Zastanawiam się, gdzie mogę przechowywać i pobierać wartości ciągów, prawie za darmo i szybko? – nearpoint

+0

Nie byłoby sensu przechowywać dataUrl na Amazon S3, zobacz moją edycję. – saimeunt

+0

Jak zdobyć wiele plików i ich dataUrl w base64? – Viddesh

2

Nie jestem pewien, czy to najlepszy sposób, ale możesz to łatwo zrobić za pomocą czytnika plików. W module obsługi zdarzeń Template, w którym znajduje się zawartość pliku, można przekazać plik do czytnika i uzyskać ciąg znaków base64. Na przykład coś takiego:

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