Meteor:上传图像并以base64字符串的形式保存到数据库

时间:2014-10-19 20:20:37

标签: image meteor base64 image-uploading

我有一个Meteor应用程序,我有兴趣以最简单的方式使图像上传工作。

我能想到的最简单的方法是以某种方式将图像转换为客户端上的base64字符串,并将其作为字符串保存到数据库中。

如何将用户文件系统上的图像转换为base64字符串,然后将其保存到数据库?

2 个答案:

答案 0 :(得分:8)

您可以使用HTML5文件输入:

HTML

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

然后听取更改事件并使用FileReader将本地文件作为base64数据网址读取,我们将存储在响应式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);
  }
});

然后我们可以使用反应性var值来允许/禁止表单提交并将值发送到服务器:

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

您需要定义一个将dataUrl保存到某个集合字段值的服务器方法,dataUrl的酷炫之处在于您可以将它们直接用作图像标记{ {1}}。

请注意,此解决方案非常不可扩展,因为图像数据无法缓存,并且会污染应用数据库常规通信(应该只包含类似文本的值)。

您可以从src获取base64数据,然后将其上传到Google云端存储或Amazon S3,并提供CDN背后的文件。

你也可以使用像uploadcare或filepicker那样为你做所有这些事情的服务。

编辑:

此解决方案易于实现,但主要缺点是从mongodb获取大型base64字符串会降低您的应用程序获取其他数据的速度,DDP通信始终处于活动状态且此时无法缓存,因此您的应用程序将始终重新下载图像数据来自服务器。

您不会将dataUrl保存到亚马逊,您可以直接保存图片,并且您的应用会使用带有可缓存HTTP请求的亚马逊网址来提取该图片。

文件上传有两种选择:您可以使用特定的javascript浏览器API直接从客户端上传它们,也可以在服务器的Node.js(NPM模块)API中上传它们。

如果您想从服务器上传(这通常比较简单,因为您不需要要求您的应用用户对第三方服务进行身份验证,只有您的服务器才会充当受信任的客户端与Amazon API通信),然后您可以通过方法调用以dataUrl作为参数发送用户想要上传的数据。

如果您不想深入了解所有这些内容,请考虑使用uploadcare或filepicker,但请记住这些是付费服务(就像Amazon S3 BTW一样)。

答案 1 :(得分:2)

不确定这是否是最好的方法,但您可以使用文件阅读器轻松完成此操作。在获取文件内容的Template事件处理程序中,您可以将文件传递给reader并返回base64字符串。例如,像这样:

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