Meteor:上传图像并将其保存到数据库中作为base64字符串

8

我有一个Meteor应用程序,我希望以最简单的方式实现图像上传。

我能想到的最简单的方法是在客户端将图像转换为base64字符串,然后将其保存为字符串到数据库中。

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


保存图片到服务器怎么样?有人可以发布一个可用的代码吗?我尝试使用ImageCollection.write函数但失败了。谢谢! - Badis Merabet
2个回答

8
您可以使用HTML5文件输入:

HTML

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

接着监听变化事件,并使用FileReader将本地文件读取为一个我们将存储在响应式变量中的Base64数据URL:

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

然后我们可以使用响应式变量的值来允许/禁止表单提交并将该值发送到服务器:

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 可以直接用作图像标记 src
请注意,这种解决方案高度不可扩展,因为图像数据无法缓存,并会污染应用程序数据库的常规通信(应仅包含类似文本的值)。
你可以从 dataUrl 获取base64数据并将其上传到Google Cloud Storage或Amazon S3,并通过CDN提供文件。
你还可以使用像uploadcare或filepicker这样的服务来完成所有这些工作。
编辑:
这种解决方案易于实现,但主要缺点是从mongodb获取大型base64字符串会使您的应用程序减慢从其他数据获取速度,DDP通信始终处于活动状态,目前不能缓存,因此您的应用程序将始终从服务器重新下载图像数据。
你不会将 dataUrl 保存到Amazon上,你会直接保存图像,然后使用可缓存的HTTP请求和Amazon URL从你的应用程序中获取它。
在文件上传时,你有两个选择:你可以使用特定的javascript浏览器API直接从客户端上传它们,也可以使用Node.js(NPM模块)API在服务器中上传它们。
如果你想从服务器上传(通常更简单,因为你不需要要求应用程序用户对第三方服务进行身份验证,只需你的服务器作为受信任的客户端与Amazon API通信),那么你可以通过带有 dataUrl 参数的方法调用发送用户想要上传的数据。
如果你不想深入研究所有这些内容,请考虑使用uploadcare或filepicker,但请记住,这些都是付费服务(Amazon S3也是)。

啊,谢谢你的回复和关于扩展性的评论。我不知道,我想使用base64的原因是因为我不必处理上传文件并将其保存到亚马逊,然后再获取文件链接。我认为这很容易,因为我可以像处理任何数据一样处理图像,并使用img src在页面上填充它。所以我想你建议将字符串存储在亚马逊S3或其他地方会起作用。这仍然比传输实际图像文件要容易。我想知道在哪里可以存储和检索字符串值,几乎免费且快速? - Nearpoint
这样将dataUrl存储在Amazon S3上没有任何意义,详见我的编辑。 - saimeunt
如何获取多个文件及其dataUrl的base64? - Viddesh

2

不确定这是否是最佳方法,但您可以轻松使用文件读取器完成此操作。在获取文件内容的模板事件处理程序中,您可以将文件传递给读取器并返回一个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);
  }
});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接