Question

I've been trying to resize images client side (using HTML5) before upload. It resizes it and sends through a base64 string, but it seems to be broken. The base64 string has spaces and line breaks and weird things, even if I take them out, it seems to still be broken. This is my HTML:

        <div class="form-group">
            <canvas id="canvas"></canvas>
            <label for="fileToUpload">Select Files to Upload</label>
            <input type="file" id="FileUpload1" name="FileUpload1" />
            <output id="filesInfo"></output>
        </div>

And of course my javascript:

<script type="text/javascript">
    if (window.File && window.FileReader && window.FileList && window.Blob) {
        document.getElementById('FileUpload1').onchange = function () {
            var files = document.getElementById('FileUpload1').files;
            for (var i = 0; i < files.length; i++) {
                resizeAndUpload(files[i]);
            }
        };
    } else {
        alert('The File APIs are not fully supported in this browser.');
    }

    function resizeAndUpload(file) {
        var reader = new FileReader();
        reader.onloadend = function () {

            var tempImg = new Image();
            tempImg.src = reader.result;
            tempImg.onload = function () {

                var MAX_WIDTH = 400;
                var MAX_HEIGHT = 300;
                var tempW = tempImg.width;
                var tempH = tempImg.height;
                if (tempW > tempH) {
                    if (tempW > MAX_WIDTH) {
                        tempH *= MAX_WIDTH / tempW;
                        tempW = MAX_WIDTH;
                    }
                } else {
                    if (tempH > MAX_HEIGHT) {
                        tempW *= MAX_HEIGHT / tempH;
                        tempH = MAX_HEIGHT;
                    }
                }

                var canvas = document.getElementById('canvas');
                canvas.width = tempW;
                canvas.height = tempH;
                var ctx = canvas.getContext("2d");
                ctx.drawImage(this, 0, 0, tempW, tempH);
                var dataURL = canvas.toDataURL("image/jpeg");

                var xhr = new XMLHttpRequest();
                xhr.onreadystatechange = function (ev) {
                    document.getElementById('filesInfo').innerHTML = 'Done!';
                };

                xhr.open('POST', 'Upload', true);
                xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
                alert(dataURL);
                var data = 'image=' + dataURL;
                xhr.send(data);
            }

        }
        reader.readAsDataURL(file);
    }
</script>

The dataURL variable, that's what contains the bad base64 string.

Was it helpful?

Solution

Here is your problem:

Base 64 encoded string includes characters like / and + , which as you can imagine have special significance if the request content type is said to be application/x-www-form-urlencoded. So, with your current code, + sign gets decoded as a space, and combinations like \n get interpreted as control characters such as line feed, new line etc.

All you have to do is encode dataURL to make sure it is safe for use as a parameter value. This is as simple as using the encodeURIComponent method.

i.e. var data = 'image=' + encodeURIComponent(dataURL);

Hope this helps.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top