Meteor CollectionFS 插入服务器端。

3

大家好,我使用的是collectionfs + gridfs + cfs文件系统,我在collectionfs文档中发现了如何在客户端插入文件的方法,像这样:

Template.myForm.events({
  'change .myFileInput': function(event, template) {
    FS.Utility.eachFile(event, function(file) {
      Images.insert(file, function (err, fileObj) {
        //Inserted new doc with ID fileObj._id, and kicked off the data upload using HTTP
      });
    });
  }
});

在这种情况下,会在客户端插入文件,但在我的情况下,我删除了不安全的内容,因此无法在客户端上插入文件,我试图在服务器端完成。所以这是我的代码:
Template.myForm.events({
    'change . myFileInput': function (event, template) {
        FS.Utility.eachFile(event, function (file) {
            var reader = new FileReader();
            reader.onload = function (fileLoadEvent) {
                Meteor.call('ImageUpload', file, reader.result, function (err, res) {
                    if (err) {
                        console.log(err);
                    } else {
                        alert(res);
                    }
                });
            };
            reader.readAsBinaryString(file);


        });
    }
});

server.js :

Meteor.methods({
    ImageUpload: function (fileInfo, fileData) {
        console.log(fileInfo);
        Images.insert(fileInfo, fileData, function (err, fileObj) {
            if (err) console.log(err)
            else {
                //Inserted new doc with ID fileObj._id, and kicked off the data upload using HTTP
                console.log(fileObj);
                return fileObj._id;
            }
        });
    }
});

但它仍然不能工作,请帮助我如何修复这个问题。 如何在服务器端插入?

它在客户端上无法工作,因为您必须定义允许/拒绝规则。我建议您在客户端上执行此操作 ;) 请查看Meteor文档。 - chaosbohne
哦,但我已经移除了不安全的部分,所以无法从客户端插入,它总是出错。 - yozawiratama
你定义了允许/拒绝规则吗? - chaosbohne
抱歉,我不知道那个,我应该在哪里定义它?也许有一个例子吗? - yozawiratama
2个回答

7

以下是您需要的示例。我没有测试它,但它展示了您需要遵循的步骤。

首先定义一个集合:

我认为这一步已经很清楚了。

var postImagesStoreFS = new FS.Store.FileSystem("postImages", {
  path: "~/workspace/uploads/"
});

新增了一些过滤器。以防您需要这样的东西。

PostImages = new FS.Collection('postImages', {
  stores: [postImagesStoreFS ],
  filter: {
  maxSize: 3145728,
  allow: {
    contentTypes: ['image/*'],
    extensions: ['png', 'PNG', 'jpg', 'JPG', 'jpeg', 'JPEG']
  }
});

现在您可以在同一个*.js文件中定义允许和拒绝函数。如果您删除不安全的包,则所有插入/更新/删除都必须通过allow/deny函数。如果命令通过allow回调,则可以将其插入到集合中(如果没有使其无效的deny函数)。
在这个例子中,我只想在有用户并且图像的元数据用户是该用户本身时插入图像。您需要自己设置元数据用户。为了测试,只需在每个allow函数中返回true,就像Pent的示例中所示。请查看Meteor文档以获取关于allow/deny更多信息:http://docs.meteor.com/#allow
PostImages.allow({
  insert: function(userId, doc) {
    return (userId && doc.metadata.owner === userId);
  },
  update: function(userId, doc, fieldNames, modifier) {
    return (userId === doc.metadata.owner);
  },
  remove: function(userId, doc) {
    return false;
  },
  download: function(userId) {
    return !!userId;
  }
});

客户端模板应该按照您发布的那样工作。如果您想使用一些元数据,我添加了一个更大的示例。
Template.myForm.events({
  'change .myFileInput': function(event, template) {
    FS.Utility.eachFile(event, function(file) {
      var fsFile = new FS.File(file);
      fsFile.metadata = {owner: Meteor.userId()};
      Images.insert(fsFile, function (err, fileObj) {

      });
    });
  }
});

这应该是你所需的一切。


哇,谢谢,它可以工作了,但是为什么我会遇到这个错误呢?http://localhost:3000/cfs/files/postImages/i2uWz6MHNxqRbcBjA/heart.png?store=postImages 403(禁止) - yozawiratama
为什么该URL被禁止访问? - yozawiratama
你从哪里获取URL? - chaosbohne
chaosbohne,你能确认在allow规则中获取到元数据吗?我正在使用gridfs进行操作,设置了元数据(并且可以在数据库中看到),但是如果我在allow规则中使用console.log(doc),我就看不到任何元数据。 - Peter Nunn
1
你必须在客户端事件中设置元数据。请参考我的示例或https://github.com/CollectionFS/Meteor-CollectionFS#add-custom-metadata-to-a-file-before-inserting获取另一个示例。注意,元数据必须设置为新的FS.File实例。 - chaosbohne

0
确保像这样应用允许和拒绝规则:
Images.allow({
  insert: function() { return true },
  update: function() { return true },
  remove: function() { return false }
});

如果使用流式处理,更新也必须被应用


如果你只是想测试,这样做还可以。但是从安全角度考虑,如果你想控制谁可以更改事物,这并不是一个好方法。 - Peter Nunn
这是为了允许公共上传并假设没有用户帐户,就像imgur一样。 - Pent

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接