Dropbox direct upload files from browser

Dropbox just posted a blog with instructions on how to do this. You can find it at https://blogs.dropbox.com/developers/2016/03/how-formio-uses-dropbox-as-a-file-backend-for-javascript-apps/ (Full disclosure, I wrote the blog post.)

Here is how to upload a file.

/**
 * Two variables should already be set.
 * dropboxToken = OAuth token received then signing in with OAuth.
 * file = file object selected in the file widget.
 */

var xhr = new XMLHttpRequest();

xhr.upload.onprogress = function(evt) {
    var percentComplete = parseInt(100.0 * evt.loaded / evt.total);
    // Upload in progress. Do something here with the percent complete.
};

xhr.onload = function() {
    if (xhr.status === 200) {
        var fileInfo = JSON.parse(xhr.response);
        // Upload succeeded. Do something here with the file info.
    }
    else {
        var errorMessage = xhr.response || 'Unable to upload file';
        // Upload failed. Do something here with the error.
    }
};

xhr.open('POST', 'https://content.dropboxapi.com/2/files/upload');
xhr.setRequestHeader('Authorization', 'Bearer ' + dropboxToken);
xhr.setRequestHeader('Content-Type', 'application/octet-stream');
xhr.setRequestHeader('Dropbox-API-Arg', JSON.stringify({
    path: '/' +  file.name,
    mode: 'add',
    autorename: true,
    mute: false
}));

xhr.send(file);

Then to download a file from dropbox do this.

var downloadFile = function(evt, file) {
  evt.preventDefault();
  var xhr = new XMLHttpRequest();
  xhr.responseType = 'arraybuffer';

  xhr.onload = function() {
    if (xhr.status === 200) {
      var blob = new Blob([xhr.response], {type: ’application/octet-stream’});
      FileSaver.saveAs(blob, file.name, true);
    }
    else {
      var errorMessage = xhr.response || 'Unable to download file';
      // Upload failed. Do something here with the error.
    }
  };

  xhr.open('POST', 'https://content.dropboxapi.com/2/files/download');
  xhr.setRequestHeader('Authorization', 'Bearer ' + dropboxToken);
  xhr.setRequestHeader('Dropbox-API-Arg', JSON.stringify({
    path: file.path_lower
  }));
  xhr.send();
}

FileSaver and Blob will not work on older browsers so you could add a workaround to them.

As other answers have noted, each session uploading or downloading the file will need to have access to a dropbox token. Sending someone else's token to a user is a security issue since having the token will give them complete control over the dropbox account. The only way to make this work is to have each person authenticate with Dropbox and get their own token.

At Form.io we've implemented both the authentication and the upload/download into our platform. This makes it really easy to build web apps with dropbox as a backend for files.