spring mvc4 中使用 juploader 上传文件 在ie8中异常

原来一直是在.net平台下使用juploader组件上传文件,后台也没有用mvc的方式,使用的是handler接收请求,现在尝试着在java平台上使用spring mvc的框架继续使用juploader组件上传文件,却遇到了很多问题,好在目前都已经解决了,因为刚刚转到java平台,有很多知识经验都不够,也许还有更好的解决方法。

由于juploader返回的内容是嵌套在一个iframe中的form表单中,并且是一个字符串(不是json),接收到后台服务器返回的字符串后,juploader会将该字符串转化为json格式的对象,代码如下:(黄色高亮部分)

var complete = function () {
            try {
                options.uploading = false;
                $('#jUploader-file' + options.id).show();
                options.button.children('span').text(options.messages.upload);

                var iframe = $('#jUploaderIframe' + options.id).get(0);
                
                // when we remove iframe from dom
                // the request stops, but in IE load
                // event fires
                if (!iframe.parentNode) {
                    return;
                }

                // fixing Opera 10.53
                if ((iframe.contentDocument &&
                iframe.contentDocument.body &&
                iframe.contentDocument.body.innerHTML == "false")
                || (iframe.contentWindow.document &&
                iframe.contentWindow.document.body &&
                iframe.contentWindow.document.body.innerHTML == "false")) {
                    // In Opera event is fired second time
                    // when body.innerHTML changed from false
                    // to server response approx. after 1 sec
                    // when we upload file with iframe
                    return;
                }



                // iframe.contentWindow.document - for IE<7
                var doc = iframe.contentDocument ? iframe.contentDocument : iframe.contentWindow.document;
                var response;

                log("innerHTML = " + doc.body.innerHTML);

                try {
                    var json = doc.body.innerHTML.replace(/<pre>(.*)<\/pre>/g, '$1');
                    response = eval("(" + json + ")");
                } catch (e) {
                    response = { "Msg": "error" };
                    //throw e;
                }
                // timeout added to fix busy state in FF3.6
                setTimeout(function () {
                    $('#jUploaderForm' + options.id).remove();
                    $('#jUploaderIframe' + options.id).remove();
                }, 10);

                options.onComplete(options.fileName, response);
            }
            catch (e) {
                setTimeout(function () {
                    $('#jUploaderForm' + options.id).remove();
                    $('#jUploaderIframe' + options.id).remove();
                }, 10);
                response = { "Msg": "error" };
                options.onComplete(options.fileName, response);
            }
        };

因此,服务器后台需要返回一个能被格式化为json对象的String,具体代码如下:

public  @ResponseBody String UploadFile(HttpServletRequest request, Model model, 
            @RequestParam("jUploaderFile") MultipartFile file,
            HttpServletResponse response) throws Exception {

        String originalFileName = file.getOriginalFilename();
        String newFileName = null;
        if(file != null && originalFileName != null && originalFileName.length() > 0)
        {
            String path = "c:\\upload\\";
            newFileName = UUID.randomUUID() +originalFileName.substring(originalFileName.lastIndexOf("."));
            File newFile = new File(path + newFileName);
            file.transferTo(newFile);
        }
        
        return "{state:\"success\"}"

这种方式在chrome、ie edge浏览器下没有问题,可以正常上传文件,在上传完成后返回成功信息,但是在ie8中却提示如下信息:

 

而实际上文件已经上传到服务器上,只是在返回的时候报错,使用httpwatch查看request以及response信息,发现response的content-type和chrome中的response不同

ie8中的request以及response信息如下图:

chrome中的request以及response信息

 

 可以看到,chrome中返回的是text/html,这符合我们的预期和代码逻辑,但是在IE8中返回的却是application/x-ms-application,具体原因不清楚,还需要好好研究spring mvc的原理,而不能仅仅停留在使用上,话说回来,目前还是要解决ie8中上传异常的问题。

尝试着将返回值设定为对象,返回的content-type在spring mvc中自动设定为json,但是出现了另一个问题,ie8中提示下载(这个问题,可以搜索“springmvc返回json数据,ie出现文件下载”的关键词,有很多),依照网上的解决方案(在springmvc.xml中修改mvc:annotation-driven等)在我的项目中依然没有解决,最后没有办法,只能用HttpServletResponse对象输出返回值,这样可以在HttpServletResponse中设定返回值的content-type,代码如下:

@RequestMapping("UploadFile")
    public  void UploadFile(HttpServletRequest request, Model model, 
            @RequestParam("jUploaderFile") MultipartFile file,
            HttpServletResponse response) throws Exception {

        String originalFileName = file.getOriginalFilename();
        String newFileName = null;
        if(file != null && originalFileName != null && originalFileName.length() > 0)
        {
            String path = "c:\\upload\\";
            newFileName = UUID.randomUUID() +originalFileName.substring(originalFileName.lastIndexOf("."));
            File newFile = new File(path + newFileName);
            file.transferTo(newFile);
        }
        response.setContentType("text/html");
        response.getWriter().write("{state:\"success\"}"); 
    }

至此,juploader组件上传文件在ie8中就可以正常使用了

 

posted @ 2018-05-26 09:30  八方鱼  阅读(355)  评论(0)    收藏  举报