解决方法
HTML
<template name="fileUpload"> <form> <input type="file" name="imageFile"> <button type="submit" disabled={{submitDisabled}}> Submit </button> </form> </template>
然后听取change事件并使用FileReader将本地文件作为base64数据url读取,我们将存储在一个被动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保存到某个集合字段值的服务器方法,dataUrls的优点是您可以直接将它们用作图像标记src.
请注意,此解决方案非常不可扩展,因为图像数据将无法缓存,并且会污染应用程序数据库常规通信(应该只包含类似文本的值).
您可以从dataUrl获取base64数据并将其上传到Google Cloud Storage或Amazon S3,并提供CDN背后的文件.
你也可以使用像uploadcare或filepicker那样为你做所有这些事情的服务.
编辑:
这个解决方案很容易实现,但主要的缺点是从mongodb获取大型base64字符串会降低你的应用程序获取其他数据的速度,DDP通信总是处于活动状态,此时无法缓存,因此你的应用程序将始终从服务器重新下载图像数据.
您不会将dataUrls保存到Amazon,您可以直接保存图像,并且您的应用程序将使用具有可缓存HTTP请求的Amazon URL提取该图像.
在文件上传方面有两种选择:您可以使用特定的javascript浏览器API直接从客户端上传它们,也可以在服务器中的Node.js(NPM模块)API中上传它们.
如果您想从服务器上传(这通常更简单,因为您不需要要求应用程序的用户对第三方服务进行身份验证,只有您的服务器将充当受信任的客户端以与Amazon API通信),然后您可以通过方法调用以dataUrl作为参数发送用户想要上传的数据.
如果您不想深入了解所有这些内容,请考虑使用uploadcare或filepicker,但请记住这些是付费服务(就像Amazon S3 BTW一样).