如何使用Meteor处理文件上传?


76

用Meteor处理文件上传的规范方法是什么?


2
这是一个模糊的问题……您是在问如何在客户端或服务器上处理它吗?无论哪种方式,我都想像(我从未使用过流星),处理文件上传的方式几乎与任何服务器相同。客户端:将POST请求发送到URL,并将文件作为请求正文的一部分。服务器端:侦听该URL上的POST请求,当一个请求进入时,读取请求主体,并对其包含的任何文件做任何您想做的事情。这基本上就是我使用节点/弹簧完成的方式...如果您可以更具体地了解需要帮助的内容,也许我会更有帮助...
JKing 2012年

29
嗨,JKing,您应该看看Meteor,这就是为什么这是一个有趣的问题:meteor.com
David

Answers:


17

当前似乎没有与HTTP服务器进行交互或执行与HTTP相关的任何操作的方法。

您唯一可以做的就是通过Meteor.methods公开的RPC方法与服务器对话,或者直接通过公开的mongoDB API与mongoDB对话。


谢谢雷诺斯。可能会尝试使用Luan的方法,并绕过JS上传器上传到S3或类似的文件。
大卫

1
@Raynos您知道公开的Mongo API是否支持GridFS吗?我看不到它。
史蒂夫·贾利姆

@stevejalim我不知道,去阅读它支持的mongo API的子集的源代码
Raynos 2012年

1
@stevejalim我查看了源代码,minimongo中没有任何GridFS支持(它们使用的软件包)
bobbywilson0 2012年

3
我在这里参加聚会有点晚,但是您也可以查看eventedmind.com的最后几集,其中我正在为流星构建文件上传器。该软件包的流媒体上传版本将在本周发布。它称为流星文件。
cmather

44

我使用了http://filepicker.io。他们将上传文件,将其存储到您的S3中,并向您返回文件所在的URL。然后,我将URL放入数据库中。

  1. 将filepicker脚本放入客户端文件夹。

    wget https://api.filepicker.io/v0/filepicker.js
    
  2. 插入文件选择器输入标签

    <input type="filepicker" id="attachment">
    
  3. 在启动时,将其初始化:

    Meteor.startup( function() {
        filepicker.setKey("YOUR FILEPICKER API KEY");
        filepicker.constructWidget(document.getElementById('attachment'));
    });
    
  4. 附加事件处理程序

    Templates.template.events({
        'change #attachment': function(evt){
            console.log(evt.files);
        }
    });
    

是的,filepicker.io!完全像Heroku一样迷人。
AbigailW 2012年

免费试用10天:(
阿拉丁2014年

8
Pfff ..我不会为上传文件到S3支付$ 100 pm。
里克2014年

6
回声@rijk,不知道为什么,有偿服务是#1投票答案.. github.com/VeliovGroup/Meteor-Filesthemeteorchef.com/recipes/uploading-files-to-amazon-s3都是免费的解决方案实现开放源库。
GFargo 2015年

1
我使用edgee:slingshot,非常适合大文件(直接上传到S3,而不是通过您的应用服务器)。
里克2015年

26

对于图像,除了不将文件写入磁盘外,我使用与Dario相似的方法。我将数据直接作为模型中的字段存储在数据库中。这对我有用,因为我只需要支持支持HTML5 File API的浏览器。而且我只需要简单的图像支持。

Template.myForm.events({
  'submit form': function(e, template) {
    e.preventDefault();
    var file = template.find('input type=["file"]').files[0];
    var reader = new FileReader();
    reader.onload = function(e) {
      // Add it to your model
      model.update(id, { $set: { src: e.target.result }});

      // Update an image on the page with the data
      $(template.find('img')).attr('src', e.target.result);
    }
    reader.readAsDataURL(file);
  }
});

19

我刚刚提出了使用Meteor.methods和HTML5 File的API上传文件的实现。让我知道你的想法。


3
因此,这些指令出奇地好。该解决方案比我预期的要容易10倍,并且代码几乎可以完美地工作。也就是说,该解决方案将图像直接上传到node.js本地文件系统。起初它在本地开发机上运行良好,但与Heroku和Nodjitsu等平台即服务(PaaS)提供商存在问题。问题是此解决方案存在文件系统权限问题。因此,此解决方案需要托管您自己的服务器,或者具有更强大的基础架构,例如Amazon Elasticbeanstalk。
AbigailW 2012年

11

有一个新包:edgee:slingshot。它不会将文件上传到流星服务器,但是这样做更好,因为它允许流星服务器专注于服务流星应用程序的主要目标,而不是处理昂贵的文件传输。

而是将文件上传到云存储服务。当前,它支持AWS S3和Google Cloud Files,但将来也将支持Rackspace Cloud Files,也许还支持Cloudinary。

您的流星服务器仅充当协调者。

直接VS间接上传

这也是一种非常通用且轻巧的包装。



7

这是此时的最佳解决方案。它使用collectionFS

meteor add cfs:standard-packages
meteor add cfs:filesystem

客户:

Template.yourTemplate.events({
    'change .your-upload-class': function(event, template) {
        FS.Utility.eachFile(event, function(file) {
            var yourFile = new FS.File(file);
            yourFile.creatorId = Meteor.userId(); // add custom data
            YourFileCollection.insert(yourFile, function (err, fileObj) {
                if (!err) {
                   // do callback stuff
                }
            });
        });
    }
});

服务器:

YourFileCollection = new FS.Collection("yourFileCollection", {
    stores: [new FS.Store.FileSystem("yourFileCollection", {path: "~/meteor_uploads"})]
});
YourFileCollection.allow({
    insert: function (userId, doc) {
        return !!userId;
    },
    update: function (userId, doc) {
        return doc.creatorId == userId
    },
    download: function (userId, doc) {
        return doc.creatorId == userId
    }
});

模板:

<template name="yourTemplate">
    <input class="your-upload-class" type="file">
</template>

我用了你所有的代码。流星正常启动,但是在单击项目后,它没有将其上传到服务器吗?没事
ErdemGüngör2014年

@ErdemGüngör检查html中的yourTemplateyour-upload-class是否与Template相同。yourTemplate .events和'change .your-upload-class '。在事件处理程序函数中添加console.log。
拉兹2014年

@Raz您是否建议使用它们?他们的devel分支(似乎是Github上的默认分支)说:“此分支目前正在积极开发中(2015-01-26)。它存在错误,API可能会继续更改。请帮助测试并修复错误,但尚未在生产中使用。” 他们的Master分支似乎很老了。我正在考虑冒险。你有什么建议?
艾尔顿·塞纳

1
@AyrtonSenna我们在小型项目的生产中使用它,并且效果很好。但是您应该在每次之后进行出色的回归测试meteor update。不仅因为这个包。
拉兹

现在不建议使用collectionFS,因此这不再是解决方案。无论如何,我用它实现了一个解决方案,并且不得不处理许多错误,最终使我完全改变为其他选择:Uploadcare。
Menda

4

如果您不需要很大的文件,或者可能只存储文件很短的时间,那么此简单的解决方案将非常有效。

在您的html中...

<input id="files" type="file" />

在您的模板事件图中...

Template.template.events({
  'submit': function(event, template){
    event.preventDefault();
    if (window.File && window.FileReader && window.FileList && window.Blob) {
      _.each(template.find('#files').files, function(file) {
        if(file.size > 1){
          var reader = new FileReader();
          reader.onload = function(e) {
            Collection.insert({
              name: file.name,
              type: file.type,
              dataUrl: reader.result
            });
          }
          reader.readAsDataURL(file);
        }
      });
    }
  }
});

订阅收藏集并在模板中呈现链接...

<a href="{{dataUrl}}" target="_blank">{{name}}</a>

对于大型文件或文件密集型应用程序,这可能不是最可靠或最优雅的解决方案,但如果要实现文件的简单上载和下载/呈现,它对于所有类型的文件格式都非常适用。



2

你可以在流星路线图上看到上看到功能“文件上载模式”计划为“ 1.0之后”。因此,我们必须等待正式的方式。

目前,最好的方法之一是使用“ collectionFS”(在撰写本文时为0.3.x dev预览)。

或按此处建议使用inkfilepicker(例如filepicker.io)。它很容易使用,尽管这显然需要用户侧与Internet的连接。

如果只是玩转,您也可以利用html5功能。喜欢的东西


collectionFS非常强大,目前看来,这是最好的方法。
portforwardpodcast 2014年


2

要完成与最受欢迎的答案相同的操作而又不花费filepicker.io,请遵循此软件包的说明:https : //github.com/Lepozepo/S3

然后,使用以下类似的代码获取链接。最后,将secureLink返回的URL插入数据库。

Template.YourTemplate.events({
  "click button.upload": function() {
    var files = $("input.file_bag")[0].files;
    S3.upload(files, "/subfolder", function(e,r) {
      console.log(r);
      Session.set('secureLink', r.secure_url);
    })
  }
});
Template.YourTemplate.helpers({
  "files": function() {
    return S3.collection.find();
  },

  "secureLink": function() {
    return Session.get('secureLink');
  }
});

谢谢你$("input.file_bag")[0].files。我正在努力寻找一种从文件类型输入中获取返回数据的方法。
Adriano P
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.