The answer given by @ altemberg-andrade is more comprehensive, but if you do not need so much and something simpler, see this example:
/client/main.html
<body>
<form id="formSubmit" method="post">
<input type="file" id="arquivo" name="arquivo" />
<input type="submit" />
</form>
<a href="/upload/">ver uploads</a>
</body>
/client/main.js
import('meteor/meteor').then(({ Meteor }) => {
formSubmit = document.getElementById('formSubmit')
formSubmit.addEventListener('submit', (evt) => {
evt.preventDefault()
let file = document.querySelector('#arquivo').files[0];
let reader = new FileReader();
reader.onloadend = function () {
let buffer = new Uint8Array(reader.result)
let { type, name } = file
Meteor.call('upload', { name, type, buffer }, (err, res) => {
if(err) throw err
alert('sucesso! ${res}')
});
};
reader.readAsArrayBuffer(file)
});
});
/server/main.js
import { Meteor } from 'meteor/meteor';
import { Mongo } from 'meteor/mongo';
import { WebApp } from 'meteor/webapp';
const collUpload = new Mongo.Collection('upload')
const uploadPath = '/upload/'
WebApp.connectHandlers.use(uploadPath, (req, res, next) => {
//console.log(req._parsedUrl)
let file_id = req._parsedUrl.pathname.replace(uploadPath, '')
let arquivo = collUpload.findOne(file_id)
if(!arquivo){
let arqs = collUpload.find().fetch().map((arq) => {
return {
_id: arq._id,
name: arq.name
}
})
res.writeHead(404);
res.end(JSON.stringify(arqs, null, 2))
} else {
res.writeHead(200, {
'Content-Type': arquivo.type,
// use attachment para forçar o download
'Content-Disposition': 'inline; filename=${arquivo.name}'
});
res.end(Buffer.from(arquivo.buffer));
}
});
Meteor.methods({
upload: function(data){
return collUpload.insert(data)
}
});