- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
当我意识到由于缺乏路由而没有端点时,我正打算使用 XHR 向服务器发送文件。
然后我读到 this article并发现我可以利用 Meteor.methods
进行文件上传。现在我的上传看起来像这样:
$(function() {
$(document.body).html(Meteor.render(Template.files));
$(document).on('drop', function(dropEvent) {
_.each(dropEvent.originalEvent.dataTransfer.files, function(file) {
var reader = new FileReader();
reader.onload = function(fileLoadEvent) {
Meteor.call('uploadFile', file, reader.result);
};
reader.readAsBinaryString(file);
});
dropEvent.preventDefault();
});
$(document).bind('dragover dragenter', function(e) {
e.preventDefault();
});
});
在server/main.js
中我有这个:
var require = __meteor_bootstrap__.require; // should I even be doing this? looks like an internal method
var fs = require('fs');
var path = require('path');
Meteor.methods({
uploadFile: function(fileInfo, fileData) {
var fn = path.join('.uploads',fileInfo.name);
fs.writeFile(fn, fileData, 'binary', function(err) {
if(err) {
throw new Meteor.Error(500, 'Failed to save file.', err);
} else {
console.log('File saved to '+fn);
}
});
}
});
这只是将其写入磁盘。这似乎可行,但我不知道 Meteor 使用什么技术将数据传递给服务器上的该方法,而且我不知道如何获取进度信息。
通常我会将事件监听器附加到 xhr
对象,
xhr.upload.addEventListener("progress", uploadProgress, false);
但我认为我无法使用 .methods
访问该方法。还有其他方法可以做到这一点吗?
最佳答案
我也一直在研究这个问题,并且我有一些有效的代码。
首先澄清一下:
This seems to work, but I don't know what technology Meteor is using to pass the data to that method on the server, and I don't know how to get progress info back.
meteor 有一个 WebSockets与服务器的连接,并将其用作传输。所以每次你调用 Meteor.call或Meteor.apply它将 EJSON对您的参数(如果有)进行编码,调用服务器端的函数,并透明地返回响应。
这里的技巧是使用 HTML5's FileReader Api分块读取文件(很重要,否则大文件会使浏览器崩溃)并对每个 block 执行 Meteor.call() 。
您的代码做了两件事,但对我来说效果不佳:
好的,现在回答你的问题。如何知道您上传了多少文件?您可以使 block 足够小,以便可以使用 chunks_sent/total_chunks 作为衡量标准。 或者,您可以从 Meteor 服务器端调用中调用 Session.set( 'progress', current_size/total_size ) 并将其绑定(bind)到一个元素以使其更新。
这是一个 jQuery 插件,我一直致力于封装此功能。它并不完整,但它可以上传文件,可能对您有帮助。目前它只能通过拖放获取文件。没有“浏览”按钮。
免责声明:我对 Meteor 和 Node 还很陌生,所以有些事情可能不会按照“推荐”的方式完成,但我会随着时间的推移改进它,并最终在 Github 上给它一个家.
;(function($) {
$.uploadWidget = function(el, options) {
var defaults = {
propertyName: 'value',
maximumFileSize: 1073741824, //1GB
messageTarget: null
};
var plugin = this;
plugin.settings = {}
var init = function() {
plugin.settings = $.extend({}, defaults, options);
plugin.el = el;
if( !$(el).attr('id') || !$(el).attr('id').length ){
$(el).attr('id', 'uploadWidget_' + Math.round(Math.random()*1000000));
}
if( plugin.settings.messageTarget == null ){
plugin.settings.messageTarget = plugin.el;
}
initializeDropArea();
};
// Returns a human-friendly string representation of bytes
var getBytesAsPrettyString = function( bytes ){
var sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
if (bytes == 0) return 'n/a';
var i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024)));
return Math.round(bytes / Math.pow(1024, i), 2) + ' ' + sizes[i];
};
// Throws an exception if the file (from a drop event) is unacceptable
var assertFileIsAcceptable = function( file ){
if( file.size > plugin.settings.maximumFileSize ){
throw 'Files can\'t be larger than ' + getBytesAsPrettyString(plugin.settings.maximumFileSize);
}
//if( !file.name.match(/^.+?\.pdf$/i) ){
// throw 'Only pdf files can be uploaded.';
// }
};
var setMainMessage = function( message ){
$(plugin.settings.messageTarget).text( message );
};
plugin.getUploader = function(){
return plugin.uploader;
};
var initializeDropArea = function(){
var $el = $(plugin.el);
$.event.props.push("dataTransfer");
$el.bind( 'dragenter dragover dragexit', function(){
event.stopPropagation();
event.preventDefault();
});
$el.bind( 'drop', function( event ){
var slices;
var total_slices;
var processChunkUpload = function( blob, index, start, end ){
var chunk;
if (blob.webkitSlice) {
chunk = blob.webkitSlice(start, end);
} else if (blob.mozSlice) {
chunk = blob.mozSlice(start, end);
} else {
chunk = blob.slice(start,end);
}
var reader = new FileReader();
reader.onload = function(event){
var base64_chunk = event.target.result.split(',')[1];
slices--;
$el.text( slices + ' out of ' + total_slices + ' left' );
Meteor.apply(
'saveUploadFileChunk',
[file_name, base64_chunk, slices+1],
{ wait: true }
);
};
reader.readAsDataURL(chunk);
};
event.stopPropagation();
event.preventDefault();
event.dataTransfer.dropEffect = 'copy';
if( !event.dataTransfer.files.length ){
return;
}
const BYTES_PER_CHUNK = 1024 * 1024; // 1MB chunk sizes.
var blob = event.dataTransfer.files[0];
var file_name = blob.name;
var start = 0;
var end;
var index = 0;
// calculate the number of slices we will need
slices = Math.ceil(blob.size / BYTES_PER_CHUNK);
total_slices = slices;
while(start < blob.size) {
end = start + BYTES_PER_CHUNK;
if(end > blob.size) {
end = blob.size;
}
processChunkUpload( blob, index, start, end );
start = end;
index++;
}
});
};
init();
}
})(jQuery);
这是我的 meteor 发布方法。
Meteor.methods({
// this is TOTALLY insecure. For demo purposes only.
// please note that it will append to an existing file if you upload a file by the same name..
saveUploadFileChunk: function ( file_name, chunk, chunk_num ) {
var require = __meteor_bootstrap__.require;
var fs = require('fs');
var crypto = require('crypto')
var shasum = crypto.createHash('sha256');
shasum.update( file_name );
var write_file_name = shasum.digest('hex');
var target_file = '../tmp/' + write_file_name;
fs.appendFile(
target_file,
new Buffer(chunk, 'base64'),
{
encoding: 'base64',
mode: 438,
flag: 'a'
}
,function( err ){
if( err ){
console.log('error ' + err);
}
console.log( 'wrote ' + chunk_num );
}
);
return write_file_name;
}
});
HTH
关于meteor - 使用 Meteor 获取上传进度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14805770/
我在尝试在 Meteor.com 上托管的经历非常复杂。 我经常收到“此网站已关闭。稍后再试。”。一开始我不知道为什么,但后来我怀疑问题是我不小心恢复了“system.users”集合造成的。我尝试在
我有点好奇,与复制 Meteor 应用程序、启动 tmux session 并仅运行 meteor 相比,Meteor Up(或其他 Meteor 应用程序部署过程,如 Modulus)是否能做任何花
我与meteor 合作创建了一个应用程序。在 meteor Meteor.methods 和 Meteor.publish 用于执行数据库操作。 I know use of Meteor method
我有一个相当大的 meteor 项目并安装了几个 meteor 包。我这样做只是为了试用一个 meteor 包,看看它是否适用于我的项目。不幸的是,在确定我不需要在我的项目中安装这些包后,我没有卸载这
对于生产为什么我应该“捆绑” meteor 应用程序而不仅仅是复制 服务器上的源使用“ meteor ”命令? 基本上有什么区别: “meteor bundle app.tar.gz”,然后安装正确版
我是 Meteor 的新手,我想知道我们如何要求用户在创建帐户时上传他的图片?我正在使用基本的 Meteor 帐户来创建用户帐户。我希望用户能够上传他的图片,并且还能够在他登录时和在我网站的登录页面上
我正在学习 Meteor Angular 2 教程。在第 6 步,我随机尝试了“ meteor 更新”,这使我的样本崩溃了。更新有效,服务器正在启动。然而,浏览器屏幕现在保持空白,并且在控制台中出现错
在我的 meteor app我需要实现表格排序。现在我正在做的是设置一个 session variable对于每个列并根据要排序的项目切换其值。 任何人都可以提出更好的选择吗? 最佳答案 我推荐 表格
我向用户发送了注册电子邮件,当他输入密码和其他详细信息时,我试图重置密码,但它抛出错误 uncaught error extpected to find a document to change 正如
我运行排行榜示例。然后我更改了 leaderboard.js 中的 names 变量(Meteor.startup 函数参数初始化的一部分)中的科学家条目之一并保存了文件。 我应该期待 meteor
我有一个 meteor 1.0 应用程序。我添加了一堆包,例如:meteor add kevohagan:ramda .但我在任何地方都找不到它。我什至无法在我的系统上找到它。 在我的项目中: $>
我有一个 meteor 移动应用程序在结构上工作;我真的需要将 View 与一些页面转换拼接在一起。 我看了iron-transitioner项目,但看起来开发已经停止? (最后一次提交 6 个月前,
我在“发现 meteor ”一书之后构建了我的第一个 meteor 添加。 但是我现在遇到了以下错误: 错误:在ian:accounts-ui-bootstrap-3 中没有找到accounts_ui
是否可以在负载均衡器后面使用 Mongodb 运行 meteor 应用程序的多个实例? 似乎如果一个应用程序的多个实例在不同的服务器上运行,那么它们就不会知道其他实例对 Mongo DB 所做的更改
我在/client/main.coffee 中的新客户端代码 Xingyun = Meteor.connect "localhost:3000" System = new Meteor.Collect
在 Meteor.publish ,使用 this.error 有什么区别并简单地抛出 Meteor.Error ? 最佳答案 this.error仅在发布方法内可用。每 the docs : Sto
假设我想在 Meteor 的后端使用与 Mongo 不同的数据库,并且还想在前端使用像 D3.js 这样的可视化库。 目前有可能吗? 如果不是我自己添加它会有多复杂? 谢谢 最佳答案 https://
我已经在 Meteor 中制作了一个 watch-as-I-type 实时聊天服务,但是我在 Meteor 中的内置元素保存功能方面遇到了麻烦。基本上,当输入的文本具有焦点时,我需要不更新当前的聊天消
我想知道 Meteor 是否可以与我的用例一起使用。 我有一个可在 App Store 上使用的移动应用程序。这个应用程序包含一个小调查,用户将在没有互联网连接的情况下做出回应。然后用户将关闭应用程序
关闭。这个问题是off-topic .它目前不接受答案。 想改善这个问题吗? Update the question所以它是 on-topic对于堆栈溢出。 8年前关闭。 Improve this q
我是一名优秀的程序员,十分优秀!