您可以使用 HTML5 文件输入:
HTML
<template name="fileUpload">
<form>
<input type="file" name="imageFile">
<button type="submit" disabled={{submitDisabled}}>
Submit
</button>
</form>
</template>
然后监听 change 事件并使用 FileReader 将本地文件读取为我们将存储在响应式 var 中的 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);
}
});
然后我们可以使用响应式 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 保存到亚马逊,而是直接保存图像,然后您的应用会使用带有可缓存 HTTP 请求的亚马逊 URL 来获取它。
关于文件上传,您有两种选择:您可以使用特定的 JavaScript 浏览器 API 直接从客户端上传,也可以在服务器的 Node.js(NPM 模块)API 中上传。
如果您想从服务器上传(这通常更简单,因为您不需要要求您的应用用户针对第三方服务进行身份验证,只有您的服务器将充当受信任的客户端与Amazon API),然后您可以通过以dataUrl 作为参数的方法调用发送用户想要上传的数据。
如果您不想深入研究所有这些内容,请考虑使用 uploadcare 或 filepicker,但请记住,这些是付费服务(就像 Amazon S3 BTW 一样)。