Async HTML5 File Uploads with Node / Express Framework

File uploads with HTML5 these days is easy as pie, especially when you have a framework that handles everything for you, internally.  Combining Node, the Express framework and a little HTML5 magic with FormData and XMLHttpRequest, we can create a very simple file uploader that can support large files.

The Express framework supports multi-part uploads through its bodyParser middleware which utilizes the node-formidable module internally.



Start off with the client side.
<div class="progress" id="progress" style="width:100%">
<div class="bar bar-success" style="width:100%"><p id=progressDisplay>0%</p></div>
</div>
<form enctype="multipart/form-data" action="/mUpload" method="post" id="fileForm">
<input type="file" id="fileField">
<a class="btn btn-small btn-primary" id="addFile">Upload File</a>
</form>
view raw form.html hosted with ❤ by GitHub


Add the button click event with a bootstrap progress indicator
handler = ()->
document.getElementById("fileField").files
# Make sure a file is selected first
if files.length <= 0
alert('choose a file, first')
return
file = files[0]
fd = new FormData()
fd.append("fileForm", file)
xhr = new XMLHttpRequest()
# define our finish fn
loaded = ()->
alert('finished uploading')
$("#addFile").one "click", handler
xhr.addEventListener 'load', loaded, false
# add progress indicator
xhr.upload.onprogress = (e)->
percent = Math.round((e.loaded * 100) / e.total)
$("#progress").width "#{percent}%"
$("#progressDisplay").html "#{percent}%"
xhr.open "post", "/mUpload"
xhr.send fd
$(document).onReady ()->
$("#addFile").one "click", handler
view raw handler.coffee hosted with ❤ by GitHub




Add the server route.
mUpload = (req, res)->
file = req.files["fileForm"]
tmpPath = file.path
fileName = file.name
dest = __dirname + "/#{fileName}"
fs.readFile tmpPath, (err, data)->
fs.writeFile dest, data, (err)->
if err
console.log err
res.end({success: true})
module.exports = mUpload
view raw mUpload.coffee hosted with ❤ by GitHub