all articles

ie9 ajax file upload

2015-08-05 @sunderls

ie9 file upload ajax js

descrition, bug

IE9 cannot send file by xmlhttprequest, we have to try another way around to implement ajax uploading.

Of course you can try using jquery plugin, but here we offer you some simple code if you want do it by yourself, and maybe you can understand it better.

The key is attribute:target

the target attribute of form is the key of this workaround. Normally, we set action to indicate the location of submitting, the page will reload itself as default, but if we set target="_blank", the page will load in a new tab, which mean we can control where the post-submit page will load.

more interestingly, we can set the target to a hidden iframe.

so we have this workaround

workaround

1. we predefine a html template , named 'uploader'. We may have multiple uploaders, so template is the right thing.

<!-- uploader should be hidden -->
<div id="uploader">
    <form acti method="POST" enctype="multipart/form-data" target="iframeUpload{{id}}">
    <input type="file" name="{{name}}">
    </form>
    <iframe name="iframeUpload{{id}}"></iframe>
</div>

2.when we do ajax uploading, like $fileInput.on('change')

if (isIE && isVersion < 10){
    // suppose we can render the tmpl
    var $uploader = $.render('#uploader', {
        id: +new Date() // unique id,
    });

    var $iframe = $uploader.find('iframe');

    // when iframe is loaded, we judget whether it failed or success
    $iframe.one('load', function(){
        try {
            var result = JSON.parse($($iframe.contentDocument.body).text());
            // judge the result
        } catch(e){
            // failed
        }
    })

    var $form = $uploader.form();

    // copy the elemnt won't get the file data, so have to use replaceWith
    $form.find('input[type="file"]').replaceWidth($realFileInput);

    $form.submit();

} else {
    // do the uploading in ajax way
    $.post(/*params*/);
}

3.server side

3.1 the upload api should have return header of 'Content-type: text/html'. since IE9 will pop download alert for 'json/application'.

3.2 the upload api url should enable x-frame in Header. 'X-FRAME-OPTIONS: SAMEORIGIN'

https://developer.mozilla.org/ja/docs/HTTP/X-Frame-Options

3.3 if you need to implement error-code, try it in Header. since IE9 redirect you to error-page when error, which cause cross-domain dom accessing, which is not simple.