Create a Meteor app and put the client_/server_ files in a client/server directories. Also, create a public dir to save the uploaded files.
-
-
Save dariocravero/3922137 to your computer and use it in GitHub Desktop.
Template.example.events({ | |
'change input': function(ev) { | |
_.each(ev.srcElement.files, function(file) { | |
Meteor.saveFile(file, file.name); | |
}); | |
} | |
}); |
<template name="example"> | |
<input type=file /> | |
</template> |
/** | |
* @blob (https://developer.mozilla.org/en-US/docs/DOM/Blob) | |
* @name the file's name | |
* @type the file's type: binary, text (https://developer.mozilla.org/en-US/docs/DOM/FileReader#Methods) | |
* | |
* TODO Support other encodings: https://developer.mozilla.org/en-US/docs/DOM/FileReader#Methods | |
* ArrayBuffer / DataURL (base64) | |
*/ | |
Meteor.saveFile = function(blob, name, path, type, callback) { | |
var fileReader = new FileReader(), | |
method, encoding = 'binary', type = type || 'binary'; | |
switch (type) { | |
case 'text': | |
// TODO Is this needed? If we're uploading content from file, yes, but if it's from an input/textarea I think not... | |
method = 'readAsText'; | |
encoding = 'utf8'; | |
break; | |
case 'binary': | |
method = 'readAsBinaryString'; | |
encoding = 'binary'; | |
break; | |
default: | |
method = 'readAsBinaryString'; | |
encoding = 'binary'; | |
break; | |
} | |
fileReader.onload = function(file) { | |
Meteor.call('saveFile', file.srcElement.result, name, path, encoding, callback); | |
} | |
fileReader[method](blob); | |
} |
/** | |
* TODO support other encodings: | |
* http://stackoverflow.com/questions/7329128/how-to-write-binary-data-to-a-file-using-node-js | |
*/ | |
Meteor.methods({ | |
saveFile: function(blob, name, path, encoding) { | |
var path = cleanPath(path), fs = __meteor_bootstrap__.require('fs'), | |
name = cleanName(name || 'file'), encoding = encoding || 'binary', | |
chroot = Meteor.chroot || 'public'; | |
// Clean up the path. Remove any initial and final '/' -we prefix them-, | |
// any sort of attempt to go to the parent directory '..' and any empty directories in | |
// between '/////' - which may happen after removing '..' | |
path = chroot + (path ? '/' + path + '/' : '/'); | |
// TODO Add file existance checks, etc... | |
fs.writeFile(path + name, blob, encoding, function(err) { | |
if (err) { | |
throw (new Meteor.Error(500, 'Failed to save file.', err)); | |
} else { | |
console.log('The file ' + name + ' (' + encoding + ') was saved to ' + path); | |
} | |
}); | |
function cleanPath(str) { | |
if (str) { | |
return str.replace(/\.\./g,'').replace(/\/+/g,''). | |
replace(/^\/+/,'').replace(/\/+$/,''); | |
} | |
} | |
function cleanName(str) { | |
return str.replace(/\.\./g,'').replace(/\//g,''); | |
} | |
} | |
}); |
Works for me on Meteor 1.0 replacing :
ev.srcElement.files -> ev.currentTarget.files
chroot = Meteor.chroot || 'public'; -> chroot = Meteor.chroot || (process.env['PWD'] +'/public') ;
fs = meteor_bootstrap.require('fs') -> fs = Npm.require('fs');
Thanks a lot !
add for meteor 1.0
Meteor.methods({
saveFile: function(blob, name, path, encoding) {
check(blob, Match.Any);
check(name, String);
check(path, String);
check(encoding, String);
I am on meteor 1.0,
Chrome && Opera thowing an error shown below..
Uncaught TypeError: Cannot read property 'files' of undefined
When I tried on Firefox : Error is shown below
TypeError: ev.srcElement is undefined
please help
it worked perfectly for me...Thanks!
TypeError: ev.srcElement is undefined
Works for me on Meteor 1.0.1 and 1.0.2 replacing :
client_save_file.js
30 //Meteor.call('saveFile', file.srcElement.result, name, path, encoding, callback);
31 Meteor.call('saveFile', file.target.result, name, path, encoding, callback);
Can't get this to work in Meteor 1.0.3. Made fixes in comment list. Fails silently without file being written to disk. Permissions are properly set.
I am on Meteor 1.1.0.2 & I get following exception:
Exception while invoking method 'saveFile' TypeError: Object # has no method 'require'
with meteor 1.1.0.2 works perfect for me, thank you;
the only thing I've changed is
fs = __meteor_bootstrap__.require('fs')
with
fs = Npm.require('fs')
inside the method
the given code is not wokring.
HTML code is written in js file
and js file is written in html file. Blunder mistake
Do you have anywhere full source code where save file is working?
Any one there?
How to change this code to fs write stream, as it is not perfect for Bigger Uploads?, Can you suggest something?
After looking into different possible solutions to file uploads with Meteor 1.3 and React, I couldn't find a suitable solution. This script helped a great deal. I can upload after a few small tweaks. Of course, for Meteor 1.3 and 1.4, it works without an error after installing fs rather than using fs = Npm.require('fs'):
meteor npm install --save fs
Then, in the server_save_files.js, I added this line on the top:
import fs from 'fs';
Next thing to figure out is: How to implement a progress bar for the upload?
Need to make the following changes to have this working in meteor 1.3
- import fs from 'fs'; (instead of fs = meteor_bootstrap.require('fs'))
- Change chroot to chroot = '../../../../../public';
- In helper function change the ev.srcElement.files to ev.currentTarget.files
Works like a charm after that. Thanks for the tutorial.
code is not working. :(
# Thanks alot man #dariocravero
Working.
Without any package.
Thanks
can anyone tell how to create persistence storage in development mode for meteor. Whenever server starts either remove data or give this error
Error: EBUSY: resource busy or locked, rmdir 'C:\Users\admins\Desktop\tripsy\dummy.meteor\local\build\programs\server'
at Error (native)
@gabrielhpugliese
I tried your example meteor-file-upload got this error
Errors prevented startup:
While building package
iron-dynamic-template
:error: no such package: 'blaze'