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

后端 未结 1 1366
醉话见心
醉话见心 2021-02-02 17:58

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.

相关标签:
1条回答
  • 2021-02-02 18:35

    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.

    0 讨论(0)
提交回复
热议问题