Problems uploading binaries with JavaScript FileReader API

New to javascript without understanding this, please help!

I am trying to use the Javascript FileReader API to read files to upload to the server. So far, it works fine for text files.

When I try to download binaries like image / .doc the files seem to be corrupted and won't open.

Using dojo on the client side and java on the server side, with dwr to handle remote method calls. Code:

Using html file input, so user can select multiple files at once:

<input type="file" id="fileInput" multiple>

      

And the javascript code that reads the content of the file:

        uploadFiles: function(eve) {
        var fileContent = null;

        for(var i = 0; i < this.filesToBeUploaded.length; i++){
            var reader = new FileReader();
            reader.onload = (function(fileToBeUploaded) {
                return function(e) {
                    fileContent = e.target.result;
                    // fileContent object contains the content of the read file
                };
            })(this.filesToBeUploaded[i]);

            reader.readAsBinaryString(this.filesToBeUploaded[i]);
        }            
    }

      

The fileContent object will be sent as a parameter to the java method that will write to the file.

    public boolean uploadFile(String fileName, String fileContent) {
    try {
        File file = new File("/home/user/files/" + fileName);
        FileOutputStream outputStream = new FileOutputStream(file);
        outputStream.write(fileContent.getBytes());
        outputStream.close();
    } catch (FileNotFoundException ex) {
        logger.error("Error uploading files: ", ex);
        return false;
    } catch (IOException ioe) {
        logger.error("Error uploading files: ", ioe);
        return false;
    }
    return true;
}

      

I have read several answers suggesting using xhr and servlets to achieve this.

Is there a way to use FileReader so that it can read any type of file (text, image, Excel, etc.)?

I tried using reader.readAsBinaryString()

and reader.readAsDataUrl()

(decoded the base64 fileContent before writing to the file) but they didn't seem to work.

PS: 1. Also, after trying reader.readAsArrayBuffer()

, the resulting object ArrayBuffer

shows some byteLength

but no content, and when this is passed to the server, all I can see is this {}

.

  1. This bit of code is only intended to work with newer versions of browsers.
+3


source to share


2 answers


Thanks to N.M. So it looks like ArrayBuffer objects cannot be used directly and the DataView must be created to use them. Following is the work -

    uploadFiles: function(eve) {
    var fileContent = null;

    for(var i = 0; i < this.filesToBeUploaded.length; i++){
        var reader = new FileReader();
        reader.onload = (function(fileToBeUploaded) {
            return function(e) {
                fileContent = e.target.result;
                var int8View = new Int8Array(fileContent);
                // now int8View object has the content of the read file!
            };
        })(this.filesToBeUploaded[i]);

        reader.readAsArrayBuffer(this.filesToBeUploaded[i]);
    }            
}

      



Refer to NM's comments on links to related pages.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Typed_arrays

+2


source


Example



<html>
    <head>
        <link rel="stylesheet" href="http://code.jquery.com/ui/1.11.3/themes/smoothness/jquery-ui.css">
        <script src="http://code.jquery.com/jquery-1.10.2.js"></script>
        <script src="http://code.jquery.com/ui/1.11.3/jquery-ui.js"></script>
    </head>
    <body>
        <script>
            function PreviewImage() {
            var oFReader = new FileReader();
            oFReader.readAsDataURL(document.getElementById("uploadImage").files[0]);
            oFReader.onload = function (oFREvent) {
                var sizef = document.getElementById('uploadImage').files[0].size;
                document.getElementById("uploadPreview").src = oFREvent.target.result;
                document.getElementById("uploadImageValue").value = oFREvent.target.result; 
            };
        };
        jQuery(document).ready(function(){
            $('#viewSource').click(function ()
            {
                var imgUrl = $('#uploadImageValue').val();
                alert(imgUrl);

                //here ajax
            });
        });
        </script>
        <div>
            <input type="hidden" id="uploadImageValue" name="uploadImageValue" value="" />
            <img id="uploadPreview" style="width: 150px; height: 150px;" /><br />
            <input id="uploadImage" style="width:120px" type="file" size="10" accept="image/jpeg,image/gif, image/png" name="myPhoto" onchange="PreviewImage();" />
        </div>
        <a href="#" id="viewSource">Source file</a>
    </body>
</html>

      

+1


source







All Articles