Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to upload a file (attachment) from the browser?

Tags:

couchdb

I don't get attachment upload for the browser to work.

Some hints are here, others there. The docs are quite good but I'm unable to translate that to a AJAX upload.

I'm looking for a super simple HTML/JavaScript example (with or w/o jQuery) of how to upload a file from (relatively modern) browser to the db without making use of jquery.couch.app.js wrapper or stuff. The simpler the besser.

Any help appreciated.

like image 409
Aron Woost Avatar asked Aug 08 '12 12:08

Aron Woost


People also ask

How do I send an attachment as a link?

To get started, in your Outlook desktop app go into Files, and then Options, and look within the General section for Attachment Options. Select Always share them as links and click Ok. That's all you need to do to change your default, and you're now ready to send attachments as links!


1 Answers

Alright, here's your pure JavaScript file upload implementation.

The basic algorithm is like this:

  1. Get the file from the file input element
  2. Get the file name and type off the file object
  3. Get the latest document revision of the document you want to attach the file to
  4. Attach the file to document using the fetched revision

The HTML part basically consists of a simple form with two elements, an input of type file and a button of type submit.

<form action="/" method="post" name="upload">
  <input type="file" name="file" />
  <button type="submit" name="submit">Upload</button>
</form>

Now to the JavaScript part.

window.onload = function() {
    var app = function() {
        var baseUrl = 'http://127.0.0.1:5984/playground/';
        var fileInput = document.forms['upload'].elements['file'];
        document.forms['upload'].onsubmit = function() {
            uploadFile('foo', fileInput.files[0]);
            return false;
        };

        var uploadFile = function(docName, file) {
            var name = encodeURIComponent(file.name),
            type = file.type,
            fileReader = new FileReader(),
            getRequest = new XMLHttpRequest(),
            putRequest = new XMLHttpRequest();

            getRequest.open('GET',  baseUrl + encodeURIComponent(docName),
                true);
            getRequest.send();
            getRequest.onreadystatechange = function(response) {
                if (getRequest.readyState == 4 && getRequest.status == 200) {
                    var doc = JSON.parse(getRequest.responseText);
                    putRequest.open('PUT', baseUrl +
                        encodeURIComponent(docName) + '/' +
                        name + '?rev=' + doc._rev, true);
                    putRequest.setRequestHeader('Content-Type', type);
                    fileReader.readAsArrayBuffer(file);
                    fileReader.onload = function (readerEvent) {
                        putRequest.send(readerEvent.target.result);
                    };
                    putRequest.onreadystatechange = function(response) {
                        if (putRequest.readyState == 4) {
                            console.log(putRequest);
                        }
                    };
                }
            };
        };
    };
    app();
};

Basically, I intercept the submit event of the form by binding my own function to the form's onsubmit event and returning false.

In that event handler I call my main function with two parameters. The first one being the document name and the second one being the file to upload.

In my uploadFile() function I set the file name, file type and grab some instances. The first HTTP request is a GET request to obtain the current revision of the document. If that request succeeds I prepare the PUT request (the actual upload request) by setting the previously obtained revision, the proper content type and then I convert the file to an ArrayBuffer. Once that's done I just send the HTTP request I've just prepared and then I relax.

The standalone attachment upload scheme looks like this:

PUT host/database/document/filename?revision=latest-revision

Of course using the proper content type in the HTTP request header.

Note: I'm well aware that I'm not making use of defensive programming here at all, I did that deliberately for brevity.

like image 135
Octavian A. Damiean Avatar answered Oct 13 '22 21:10

Octavian A. Damiean