Not what you’re asking but I’d strongly recommend not saving things on the server. Use some kind of file storage service instead. The reason is that maintenance becomes a nightmare when you have files stored in the server. e.g What happens if your app needs to use 2 or more servers? Even if you don’t plan on using more than one server, being able to rebuild or redeploy a server without worrying about losing data is a huge peace of mind.
Cheers for the reply! If this were for a larger application I’d store files in s3. Fortunately this is for a guild website which probably won’t require more than ~50 images stored during its entire life.
I’m also building this website for a friend and his guild. I’m not sure if I can convince them to use s3 or google cloud, so storing via server seems like the safest thing to do at this phase (while I try to convince them)
I think you should use Meteor.absolutePath for path.
If you want to use img src you need the images uploaded to public folder. But this will cause meteor server to restart. In fact uploading or copying a file anywhere in meteor folder will cause restart or refreshing the client. Except folders that name starts with “.” (eg: .images)
You will also need to set up a route for img src urls. Here is a sample route that I am using for uploaded or exported files.
Router.map(function() {
this.route('files', {
path: '/files/:path',
where: 'server',
action: function() {
var path = Meteor.absolutePath + '\\.static~\\' + this.params.path;
var fs = Npm.require('fs');
var file = fs.readFileSync(path);
var extention = /[^.]+$/.exec(path);
var contentType = "";
switch(extention){
case "apk":
contentType = "application/vnd.android.package-archive";
break;
case "png":
case "jpeg":
case "jpg":
contentType = 'image/' + extention;
break;
case "xls":
contentType = 'application/vnd.ms-excel';
break;
case "xlsx":
contentType = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
break;
default:
break;
}
var headers = {
'Content-type': contentType,
'Content-Disposition': "attachment; filename=" + this.params.path
};
this.response.writeHead(200, headers);
return this.response.end(file);
}
});
});
Better to add 404 condition to that sample, in my case I always have control over requested file names so I don’t need it.
If you want to serve files which are not in a sub directory of your application make sure you implement it securely. Node can access and serve any file on the disk to anyone if you don’t limit it.
Cheers for the help! I’m using Flowrouter, but your solution pointed me in the right direction!
I’m using a modified version of
var fs = Npm.require('fs');
WebApp.connectHandlers.use(function(req, res, next) {
var re = /^\/uploads_url_prefix\/(.*)$/.exec(req.url);
if (re !== null) { // Only handle URLs that start with /uploads_url_prefix/*
var filePath = process.env.PWD + '/.uploads_dir_on_server/' + re[1];
var data = fs.readFileSync(filePath);
res.writeHead(200, {
'Content-Type': 'image'
});
res.write(data);
res.end();
} else { // Other urls will have default behaviors
next();
}
});
Found here
On my server, as flowrouter can only run in Lib. Works like a charm