Mongodb Meteor:将文件从客户端上传到Mongo集合vs文件系统vs GridFS
Meteor很棒,但它缺乏对传统文件上传的本地支持。有几个选项可用于处理文件上载: 从客户端,可以使用以下方式发送数据:Mongodb Meteor:将文件从客户端上传到Mongo集合vs文件系统vs GridFS,mongodb,file-upload,meteor,gridfs,Mongodb,File Upload,Meteor,Gridfs,Meteor很棒,但它缺乏对传统文件上传的本地支持。有几个选项可用于处理文件上载: 从客户端,可以使用以下方式发送数据: Meteor.call('saveFile',data)或collection.insert({file:data}) “POST”窗体或HTTP.call('POST') 在服务器中,文件可以保存到: 按collection.insert({file:data})的mongodb文件集合 文件系统位于/path/to/dir中 mongodb网格 这些方法的优缺点是
- Meteor.call('saveFile',data)或collection.insert({file:data})
- “POST”窗体或HTTP.call('POST')
- 按collection.insert({file:data})的mongodb文件集合
- 文件系统位于/path/to/dir中
- mongodb网格
这些方法的优缺点是什么?如何最好地实施它们?我知道还有其他选项,例如保存到第三方网站并获取url。您可以使用Meteor实现文件上传,而无需使用任何其他软件包或第三方 选项1:DDP,将文件保存到mongo集合
/***client.js***/
//将更改事件指定到输入标记中
“更改输入”:函数(事件、模板){
var file=event.target.files[0];//假设只有1个文件
如果(!文件)返回;
var reader=new FileReader();//根据HTML5文件API创建读取器
reader.onload=函数(事件){
var buffer=new Uint8Array(reader.result)//转换为二进制
Meteor.call('saveFile',buffer);
}
reader.readAsArrayBuffer(文件);//将文件作为arraybuffer读取
}
/***server.js***/
Files=新的Mongo.Collection('Files');
流星法({
“保存文件”:函数(缓冲区){
insert({data:buffer})
}
});
解释
首先,使用HTML5文件API从输入抓取文件。读卡器是使用新的FileReader创建的。该文件被读取为readAsArrayBuffer。如果您使用console.log,这个arraybuffer将返回{},DDP无法通过线路发送,因此必须将其转换为Uint8Array
当您将其放入Meteor.call中时,Meteor会自动运行EJSON.stringify(Uint8Array)并将其与DDP一起发送。您可以在chrome控制台websocket流量中检查数据,您将看到一个类似base64的字符串
在服务器端,Meteor调用EJSON.parse()并将其转换回缓冲区
专业人士
选项2:XHR,从客户端发布到文件系统
/***client.js***/
//将更改事件指定到输入标记中
“更改输入”:函数(事件、模板){
var file=event.target.files[0];
如果(!文件)返回;
var xhr=new XMLHttpRequest();
xhr.open('POST','/uploadwhere',true);
xhr.onload=函数(事件){…}
发送(文件);
}
/***server.js***/
var fs=净现值要求(“fs”);
//使用interal webapp或iron:router
WebApp.connectHandlers.use('/uploadwhere',函数(req,res){
//var start=Date.now()
var file=fs.createWriteStream('/path/to/dir/filename');
on('error',函数(error){…});
on('finish',function(){
文书标题(…)
res.end();//结束响应
//console.log('完成上传,所用时间:'+Date.now()-start);
});
req.pipe(文件);//将请求通过管道传输到文件
});
解释
抓取客户端中的文件,创建XHR对象,并通过“POST”将文件发送到服务器
在服务器上,数据通过管道传输到底层文件系统。您还可以在保存之前确定文件名、执行清理或检查文件名是否已存在等
专业人士
选项3:XHR,保存到GridFS
/***client.js***/
//与方案2相同
/***版本A:server.js***/
var db=MongoInternals.defaultRemoteCollectionDriver().mongo.db;
var GridStore=mongonternals.NpmModule.GridStore;
WebApp.connectHandlers.use('/uploadwhere',函数(req,res){
//var start=Date.now()
var file=newgridstore(db,'filename','w');
打开(函数(错误,gs){
file.stream(true);//管道完成后,true将自动关闭文件
on('error',函数(e){…});
on('end',function(){
res.end();//发送端响应
//console.log('完成上传,所用时间:'+Date.now()-start);
});
请求管道(文件);
});
});
/***版本B:server.js***/
var db=MongoInternals.defaultRemoteCollectionDriver().mongo.db;
var GridStore=Npm.require('mongodb').GridStore//还需要在package.js中添加Npm.depends({mongodb:'2.0.13'})
WebApp.connectHandlers.use('/uploadwhere',函数(req,res){
//var start=Date.now()
var file=new GridStore(db,'filename','w')。stream(true);//启动流
on('error',函数(e){…});
on('end',function(){
res.end();//发送端响应
//控制台
file size GridFS FS
100 KB 50 2
1 MB 400 30
10 MB 3500 100
200 MB 80000 1240
<template name='tryUpload'>
<p>Choose file to upload</p>
<input name="upload" class='fileupload' type='file'>
</template>
Template.tryUpload.events({
'change .fileupload':function(event,template){
console.log('change & view');
var f = event.target.files[0];//assuming upload 1 file only
if(!f) return;
var r = new FileReader();
r.onload=function(event){
var buffer = new Uint8Array(r.result);//convert to binary
for (var i = 0, strLen = r.length; i < strLen; i++){
buffer[i] = r.charCodeAt(i);
}
var toString = String.fromCharCode.apply(null, buffer );
console.log(toString);
//Meteor.call('saveFiles',buffer);
}
r.readAsArrayBuffer(f);};