Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 

Repository files navigation

#Simple File Upload Example

I've been asked a few times lately about uploading files with progress events in web applications, so I thought I'd go over it real quick with an example.

HTML

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
  </head>
  <body>
    <progress id="progress" value="0" max="100"></progress>
    <input type="file" id="filepicker"/>
    <script src="client.js"></script>
  </body>
</html>

The HTML consists of a progress bar which represents a percentage, and thus has a max of 100. An input with a type attribute of file is used as our filepicker.

Server

var fs = require('fs');
require('http').createServer(function (req, res) {
  if (req.method === 'GET') {
    fs.createReadStream(req.url === '/client.js' ? 'client.js' : 'index.html')
      .pipe(res);
  } else if (req.method === 'POST') {
    req.pipe(fs.createWriteStream(req.headers['x-filename']));
    res.setHeader('Content-Type', 'text/plain');
    res.end();
  }
}).listen(3000);

Here we create a server listening on port 3000. The first branch of the conditional in the request handler function is boilerplate; it serves the client side JavaScript when asked, else the index html. The second branch assumes the entirety of the HTTP POST's body is a single file. We then read out a non standard filename out from the HTTP headers. Non standard headers are frequently prefixed with 'X-', though node.js' http runtime library converts all headers to lowercase.

Client

var progress = document.getElementById('progress');
document.getElementById('filepicker').addEventListener('change', function (e) {
  if (e.target.files.length < 1) return;
  var xhr = new XMLHttpRequest;
  xhr.open('POST', '/upload');
  xhr.setRequestHeader('X-Filename', e.target.files[0].name);
  xhr.upload.onprogress = function (e) {
    if (e.lengthComputable) progress.value = e.loaded / e.total * 100;
  };
  xhr.send(e.target.files[0]);
});

The basis here is that we listen for the input[type=file] element's change event. We then grab the file from the change event's target.files which is an array (we could add the boolean attribute to allow multiple files to be selected). We also, send along the file's name in an additional header. Note: it looks like XMLHttpRequest.prototype.upload is only defined in IE 10+, but so are progress elements.

FormData

Why not use FormData? Ockham's Razor. FormData is much more powerful, but makes the server side logic much more complex, though there are many libraries that can help. Server side processing is much simpler in PHP as the $_FILES superglobal contains an associative array of the files.

##Additional Links

About

example for most basic file upload

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages