Ajax Upload tweaked for grails

While coding a little on gibbon’s five we stumbled upon a nice JavaScript library called file uploader. The first tests we did looked good so we took it into the project. While checking the browser compability I ran into some problems with the Internet Explorer that need to be fixed.

First of all, the return type for the IE has to be a little different – the IE needs text/plain. Also, the data send from the IE to the server looks a little different from the one WebKit and gecko: It’s a CommonsMultipartFile. Therefore I had to do some tweaking on the server side which ended in some code pretty similar to this:

if (params.qqfile instanceof org.springframework.web.multipart.commons.CommonsMultipartFile){
    returnType = 'text/plain'
    content = params.qqfile.getInputStream()
    originalFilename = params.qqfile.originalFilename
    mimeType = params.qqfile.getContentType()
} else {
    returnType = 'application/json'
    content = request.inputStream
    originalFilename = params.qqfile
    mimeType = URLConnection.guessContentTypeFromName(params.qqfile)
}

Furthermore, the plugin has to deal with older browsers and the IE by using iframes (mentioned on the website and explained in the code). This works pretty well until you come across grails, which, for whatever reason, sends pre-tags around the json code. Of course our friend the Internet Explorer is confused and is simply not evaluating the answer. A simple solution to this is to change a few lines of code in the function (fileuploader.js):

_getIframeContentJSON:function (iframe) {
    // iframe.contentWindow.document - for IE<7
    var doc = iframe.contentDocument ? iframe.contentDocument : iframe.contentWindow.document, response;

    this.log("converting iframe's innerHTML to JSON");
    this.log("innerHTML = " + doc.body.innerHTML);

    // Grails is answering with pre-tags. That might confuse the browser script therefore we better remove them.
    var cleanedAnswer = doc.body.innerHTML.replace(/<(\/)*pre>/g, '');
    this.log("grails cleaned: " + cleanedAnswer);

    try {
        response = eval("(" + cleanedAnswer + ")");
    } catch (err) {
        response = {};
    }

    return response;
}

Overall it’s a simple tweak and now it works perfectly within all the browsers we tried :)