如何使用Meteor.js上傳檔案?
注意: 本教程使用的是2014年12月15日的Meteor 1.1.3 和 cfs:standard-package 0.0.2
。由於此功能正在積極開發中,您閱讀此文時可能已有所變化。如果你有任何疑問,請隨時聯絡我。:)
問題描述
上周,我的一個朋友問我如何在Meteor項目中處理檔案上傳。我建議他使用Collection FS,並按照他們存儲庫的README.md指南。檔案上傳功能在本地主機上工作正常,但一旦部署到免費的Meteor測試服務器,就會失敗。事實上,服務器會不斷刷新,甚至無法加載頁面。
我的解釋
這個問題產生的原因是 FS.filesystem
將圖像上傳到公共資料夾目錄。由於安全考慮,除非經過適當配置,否則服務器不允許這樣做。一個解決方法是使用 GridFS 作為儲存適配器,將圖像插入到MongoDB中。
我的解決方案
安裝
首先,不要使用cfs:filesystem
,而要為您的套件使用cfs:gridfs
。
meteor add cfs:standard-packages
meteor add cfs:gridfs
語法
接下來,當聲明您的集合時,從使用 FS.Collection
切換到 FS.Store.GridFS
。
var imageStore = new FS.Store.GridFS("images")
Images = new FS.Collection("images", {
stores: [imageStore],
})
權限
然後,根據你的需求設定’deny’和’allow’規則。
Images.deny({
insert: function () {
return false
},
update: function () {
return false
},
remove: function () {
return false
},
download: function () {
return false
},
})
Images.allow({
insert: function () {
return true
},
update: function () {
return true
},
remove: function () {
return true
},
download: function () {
return true
},
})
使用者介面
在客戶端模板中添加一個檔案輸入按鈕以供使用者點擊。
<input type="file" name="..." class="myFileInput" />
像這樣處理事件:
Template.Profile.events({
"change .myFileInput": function (event, template) {
FS.Utility.eachFile(event, function (file) {
Images.insert(file, function (err, fileObj) {
if (err) {
// handle error
} else {
// handle success depending on your needs
var userId = Meteor.userId()
var imagesURL = {
"profile.image": "/cfs/files/images/" + fileObj._id,
}
Meteor.users.update(userId, { $set: imagesURL })
}
})
})
},
})
發佈/訂閱
最後,如果你已經移除了 autopublish
套件,不要忘記設定發佈和訂閱。
Meteor.publish("images", function () {
return Images.find()
})
在你的 iron:router
中訂閱它:
Router.route("/profile", {
waitOn: function () {
return Meteor.subscribe("images")
},
action: function () {
if (this.ready()) this.render("Profile")
else this.render("Loading")
},
})
我希望這個解決方案對你有所幫助。如果你正在使用Amazon S3 bucket,可以考慮使用 cfs:s3
作為適配器。如果所有其他方法都失敗了,Filepicker可以作為處理文件上傳的另一種方法。欲了解更多信息,請訪問 Filepicker的網站。