Я думаю, что я что-то упускаю. Я прочитал много сообщений/примеров и не могу сохранять изображения в своей системе (я работаю локально).
Какова моя цель?
Я пытаюсь сохранить файл, отправленный пользователем, в папку (на стороне сервера). Звучит легко? Может быть.
В чем проблема ?
Краткий ответ: я не могу понять, как сохранить файл в моей папке. Хотите больше информации?
История загрузки файла
Я читал, что для использования параметра path, такого как new FS.Store.FileSystem("thumb", { path: "/public/images/user/avatar" })
, я должен объявить свою коллекцию на стороне сервера. Но когда я звоню Avatars.insert()
(Аватары — это название моей коллекции), кажется, что его не существует. Это имеет смысл, потому что эта коллекция существует только на сервере.
Итак, я попытался объявить коллекцию как на стороне сервера, так и на стороне клиента (я читал несколько примеров об этом), и это работает! Файл правильно добавлен в MongoDB, но моя папка все еще пуста (я не уверен, но я думаю, что это потому, что Avatars.insert()
называется клиентской стороной, поэтому используемая коллекция является клиентской, той, которая не может принимать параметр path
).
Без проблем ! Я создал 2 метода Meteor (один на стороне клиента и один на стороне сервера) под названием «updateAvatarFile». С помощью этого «трюка» я могу сделать Meteor.call("updateAvatarFile", field.files[0])
, который вызывает как серверные, так и клиентские методы. Так что я могу делать некоторые вещи с пользовательским интерфейсом на стороне клиента и загружать файл в другом. Но я не могу передать файл в качестве параметра.
field.files[0]
содержит файл на стороне клиента, но на стороне сервера это пустой объект. Мой вопрос: как я могу загрузить файл?
Я не могу сделать это на стороне клиента (поскольку я не могу использовать параметр path
), но я могу передать файл на сервер. Я уверен, что что-то упускаю, но не могу понять что.
Вот как я иду:
// /client/views/templates/settings.js
Template.settings.events({
'submit #updateAvatar': function (e, template) {
e.preventDefault();
const field = document.getElementsByName('avatar')[0];
Meteor.call('updateAvatarFile', field.files[0]);
}
});
// /client/lib/clientMethods.js
Meteor.methods({
'updateAvatarFile': function (file) {
// blabla
}
});
// /server/lib/serverMethods.js
Meteor.methods({
'updateAvatarFile': function (file) {
Avatars.insert(file, function (err, fileObj) {
if (err) {
console.log(err);
} else {
console.log(fileObj);
}
});
}
});
// /server/collections/serverAvatarCollection.js
Avatars = new FS.Collection("avatars", {
stores: [
new FS.Store.FileSystem("original", { path: "/public/images/user/avatar" }),
new FS.Store.FileSystem("thumb", { path: "/public/images/user/avatar" })
],
filter: {
maxSize: 1000000, //1Mo
allow: { contentTypes: ['image/*'] }
},
onInvalid: function (message) {
//throw new Meteor.Error(403, message);
}
});
// /client/collections/clientAvatarCollection.js
// (this one is actually in a comment block)
Avatars = new FS.Collection("avatars", {
stores: [
new FS.Store.FileSystem("original"),
new FS.Store.FileSystem("thumb")
],
filter: {
maxSize: 1000000, //1Mo
allow: { contentTypes: ['image/*'] }
},
onInvalid: function (message) {
alert(message);
}
});
Я также пытался вставить файл с помощью метода на стороне клиента, но у меня тот же результат (файл добавляется в MongoDB, но не сохраняется в папке).
Использование разных значений path
тоже не сработало.
РЕДАКТИРОВАТЬ: Или, может быть, я пытаюсь использовать не тот пакет? На мой взгляд, преобразование изображения в куски и сохранение их в MongoDB звучит очень странно и плохо. Есть ли у вас какие-либо советы?
EDIT 2: ответ Мишелю Флойду (извините, ограничение на количество символов раздражает).
Во-первых, спасибо за ваш ответ!
1. В данный момент я просто пробую Meteor, поэтому у меня установлены и autopublish
, и insecure
. Отсутствие публикации/подписки на мою коллекцию не может вызвать проблемы, верно?
2. До вашего ответа я попытался настроить коллекцию, доступную как для сервера, так и для клиента, поместив avatarCollection.js
в /collections
. Я думал, что путь, который не содержит сервер или клиент, автоматически доступен для обеих сторон. Так в чем разница между /collections
и /lib
? (Я знаю, что все файлы в папке «lib» загружаются первыми). Неправильно ли размещать коллекции в /collections
? Может быть, мне создать папку /lib/collections
?
3. (последний пункт, извините за длинный комментарий) Я попробовал то, что вы посоветовали выше, но это не работает (или я делаю что-то не так, опять >‹). Когда я использую Avatars.insert()
, CollectionFS не сохраняет файл в моем локальном хранилище. Я также проверил корень моего жесткого диска на случай, если CollectionFS интерпретирует /
как корень моей машины, но это не так. С другой стороны, CollectionFS создала 4 коллекции в MongoDB (cfs._tempstore.chunks
, cfs.avatars.filerecord
, cfs_gridfs._tempstore.chunks
и cfs_gridfs._tempstore.files
) — gridfs выглядит странно. У меня установлена GridFS, но я использую FileSystem -. Эти таблицы не пусты. Вот почему я думаю, что CollectionFS разделит мой файл на куски и сохранит их в MongoDB.