Juploader 1.0 谷歌(chrome)浏览器中成功上传文件后返回信息异常

Posted 八八鱼

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Juploader 1.0 谷歌(chrome)浏览器中成功上传文件后返回信息异常相关的知识,希望对你有一定的参考价值。

 

在项目中使用了Juploader 1.0无刷新上传文件的js组件,在IE8以上没有问题,代码如下:

function InitialUploadDirectly(OnUploadFunc, buttonID, allowedExts) {
            $.jUploader({
                button: buttonID, // 这里设置按钮id
                eventType: 1, //触发类型   
                addeventbutton: buttonID, // 要绑定事件的元素的id   
                filenamed: buttonID + \'divFileName\', //存放选择的文件路径的文本框的id  
                checkMethod: function () { return checkForm(); },
                afterChoose: function (fileName) { afterUpload(fileName, buttonID); },

                allowedExtensions: allowedExts, // 设置允许上传的后缀,当然最好在服务器端也做验证

                // 开始上传事件
                onUpload: function (fileName) {
                    var url = "**.ashx";
                    if (OnUploadFunc != null) {
                        url = OnUploadFunc();
                    }
                    $.jBox.tip("正在上传文件,请稍候!", "loading");
                    return url;
                },

                // 上传完成事件
                onComplete: function (fileName, response) {
                    // response是json对象,格式可以按自己的意愿来定义,例子为: { success: true, fileUrl:\'\' }
                    console.log(response);
                    if (response.Msg == "success") {
                        AfterUploadCompleteSuccess(response.AddedFile.S_ID, fileName);

                    }
                    else if (response.Msg == "error") {
                        jBox.closeTip();
                        jBox.error("文件大小不能超过50M", "错误提示");
                    }
                    else {
                        jBox.closeTip();
                        jBox.error(response.Msg, "错误提示");
                    }
                },

                // 系统信息显示(例如后缀名不合法)
                showMessage: function (message) {

                    jBox.tip(message, \'error\');
                },

                // 取消上传事件
                onCancel: function (fileName) {
                    jBox.tip(fileName + \' 上传取消。\', \'info\');
                },

                // 自己定义文字
                messages: {
                    upload: \'添加附件...\',
                    emptyFile: "{file} 为空,请选择一个文件.",
                    invalidExtension: "{file} 后缀名不合法. 只有 {extensions} 是允许的.",
                    onLeave: "文件正在上传,如果你现在离开,上传将会被取消。"
                }
            });
        }

但是使用Chrome(我测试的版本为31)浏览器测试的时候,虽然服务器已经接收到上传的文件,并且返回了json格式的数据对象,但是前台脚本中始终得不到返回值,response始终为{“Msg”:”error”},查看Jquploader的源码,发现response是在complete事件中try catch 中异常情况中赋的值,下面代码中黄色标识的部分

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;
                }
                console.log(response);
                // 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);
            }
        };

继续调试发现下面这段代码中

var json = doc.body.innerHTML.replace(/<pre>(.*)<\\/pre>/g, \'$1\');的json始终为空,但是实际上后台是返回了值的。

继续查看源码,明白了Juploader的基本思想,是在页面中创建iframe,再在iframe中构建一个form,form的action指向上传文件的后台服务器地址,如下:

$(document.body).append(createIframe()).append(createForm());

并且在iframe的onload事件中绑定自定义的complete方法,如下:

var createIframe = function () {
            var id = \'jUploaderIframe\' + options.id;
            var iframe = $(\'<iframe id="\' + id + \'" name="\' + id + \'" src="javascript:false;" style="display:none"></iframe>\').bind(\'load\', complete);

            return iframe;
        };

这样在iframe中的form加载完成后会执行iframe的onload事件(具体iframe的onload事件的用法,可自行百度,这里不多做解释了)。

但是在调试过程中却发现onload的事件总是先执行,也就是说complete方法在执行的时候form其实还没有加载完成,以下是控制台日志显示内容:

于是怀疑是因为代码顺序的问题造成的,再看一下具体的代码

createIframe方法中:

var iframe = $(\'<iframe id="\' + id + \'" name="\' + id + \'" src="javascript:false;" style="display:none"></iframe>\').bind(\'load\', complete); 

upload方法中:

$(document.body).append(createIframe()).append(createForm());

于是调整代码在iframe append form 后,再bind iframe 的onload事件

createIframe方法中

var iframe = $(\'<iframe id="\' + id + \'" name="\' + id + \'" src="javascript:false;" style="display:none"></iframe>\')

去掉了bind  load 的事件

而在upload方法中:

var ifrm = createIframe();
$(document.body).append(ifrm).append(createForm());
ifrm.bind("load", complete);

这样修改之后,上传完成事件onComplete 的response参数就可以正常获取form 中action 页面的回传值了

以上是关于Juploader 1.0 谷歌(chrome)浏览器中成功上传文件后返回信息异常的主要内容,如果未能解决你的问题,请参考以下文章

重磅消息!Firefox,Chrome,Edge和Safari全面禁用TLS 1.0和TLS 1.1

Brave将推出的1.0版本浏览器可支持Chrome扩展功能 能进行小型加密货币交易

selenium脚本驱动chrome浏览器很慢

之前Chrome浏览器在搜索浏览历史的时候,可以通过把页面中的内容(不仅限标题)作为关键词来获取浏

一年303个漏洞,Chrome被评为“最脆弱”浏览器,Opera 最安全!网友:Opera 还有人用?...

CRX文件无法打开,按照指示使用chrome浏览器也无法打开,求解!