MapleStory MapleStory - 2 months ago 30
jQuery Question

FileReader.onload can not return successful in time

I want to get the image file stream and pass them to the background like asp.net,but every time I try to fire the onload event ,it always accomplish after the programming passed.

I tried to use setTimeout to prevent it and let it processing and waiting it Success ,but it failed .
the comment of below explains which step I failed.thanks.

$("#goodsImage").change(function (e) {
if ($("#goodsImage").val() == "")
{
alert("please choose the image you want to upload");
return;
}

var filepath = $("#goodsImage").val();

//$("#goodsImage").val();
var extStart=filepath.lastIndexOf(".");
var ext=filepath.substring(extStart,filepath.length).toUpperCase();
if(ext!=".BMP"&&ext!=".PNG"&&ext!=".GIF"&&ext!=".JPG"&&ext!=".JPEG"){
alert("only images could be uploaded");
return;
}
readFile(e.target.files[0]);
setTimeout(function () {
//I want to use setTimeOut to delay it
}, 1000);


//always undefined!!!
if ($("#hidImageStream").val() != "")
{
$.post("@Url.Action("UploadGoodImage")", { localPath: readerRs }, function (e)
{
if (e) {
$("#ImagePreviewUrl").val(e.data);
}
else {

}
});
}



});

function readFile(file) {
var reader = new FileReader();
reader.onload = readSuccess;

//always success after post request accomplished.
function readSuccess(evt) {

document.getElementById("hidImageStream").
value = evt.target.result;

};
reader.readAsText(file);
}

Answer

here is a few tips

<-- use accept and only allow image mimetype. It can accept extension to -->
<input type="file" name="pic" accept="image/*">
  • Also reading the file as readAsText is a horrible idea for binary. (All doe i saw you change to base64).
  • readAsDataURL isn't that grate either since it's ~3x larger upload and needs more cpu/memory.
  • Spoofing the filename is very easy so best is to actually test if it's a image


$("#goodsImage").change(function() {
    // We use `this` to access the DOM element instead of target
    for (let file of this.files) {
        // Test if it's a image instead of looking at the filename
        let img = new image
        img.onload = () => {
            // Success it's a image
            // upload file
            let fd = new FormData
            fd.append('file', file)

            $.ajax({
                url: 'http://example.com',
                data: fd,
                processData: false, // so jquery can handle FormData
                type: 'POST',
                success: function( data ) {
                    alert( data )
                }
            })
        }

        img.onerror = () => {
            // only images dude
        }

        img.src = URL.createObjectURL(file)
    }
})
Comments