Extjs上传文件在firefox中的bug

  • 发现问题

近来在自己瞎捣鼓中发现extjs4.1.1中在带有uploadfield的form中使用form.submit方法在firefox中存在bug,也就是上传文件时.

具体情况是:

我在写ajax请求是使用的方法是

var form = ....//from from panel get baseForm
.....//init and validate other data
form.duSubmit({
    url:'getUsers.req',
    ....//other params
    success:function(fp,o){
        alert(o.result.dataMsg);
    },
    failure:function(fp,o){
        alert(o.result.errorMs);
    }
});

 这个方法在ie中完全没有问题,但是在firefox中总是不正常,点击完提交按钮后,就一直停在正在处理的那个画面里转呀转的,就是不返回成功或失败的提示.

  • 研究问题

 在百度上google了好久好久都没找到一点有用的资料,有的大多是一些相关的问题,但没有人解决了.想想  如果不能解决这个问题,当碰到类似的功能时就不能再firefox上调试,就觉得后果很可怕,一狠心就决定自己从头开始分析这个问题,

 

在firefox的firebug中我看到有一条错误信息,意思是 result is undefined,然后还有个链接,点进去是

ext-all-debug.js文件中的Ext.form.action.Submit 的onSuccess 的方法(我开发时使用的debug版的extjs)

onSuccess: function(response) {
        var form = this.form,
            success = true,
            result = this.processResponse(response);
        if (result !== true && !result.success) {
            if (result.errors) {
                form.markInvalid(result.errors);
            }
            this.failureType = Ext.form.action.Action.SERVER_INVALID;
            success = false;
        }
        form.afterAction(this, success);
    },

 再通过firebug调试js中发现result 确实为undefined,但是为什么在ie中又正常了呢.于是我想到了可能是两个浏览器对某些对象的封装赋值存在差异,所以我继续查看processResponse方法,这个方法是其父类Ext.form.action.Action的方法

processResponse : function(response){
        this.response = response;
        if (!response.responseText && !response.responseXML) {
            return true;
        }
        return (this.result = this.handleResponse(response));
    },

 其中又使用到了Ext.form.action.Submit类中的handleResponse方法

handleResponse: function(response) {
        var form = this.form,
            errorReader = form.errorReader,
            rs, errors, i, len, records;
        if (errorReader) {
            rs = errorReader.read(response);
            records = rs.records;
            errors = [];
            if (records) {
                for(i = 0, len = records.length; i < len; i++) {
                    errors[i] = records[i].data;
                }
            }
            if (errors.length < 1) {
                errors = null;
            }
            return {
                success : rs.success,
                errors : errors
            };
        }
        return Ext.decode(response.responseText);
    }

 在这个方法中我看到了 

Ext.decode(response.responseText);

 而在调试过成功,我看到response中的responseText确实是undefined.

 到此我就郁闷了,为什么它是undefined,它既然在ie中能正常,那说明在ie中这个肯定有值,于是我想到了谁为responseText在什么时候赋值的呢?

又是进过一番查找,终于在Ext.data.Connection的onUploadComplete方法中我找到了为responseText赋值的语句

onUploadComplete: function(frame, options) {
        var me = this,
            response = {
                responseText: '',
                responseXML: null
            }, doc, contentNode;
        try {
            doc = frame.contentWindow.document || frame.contentDocument || window.frames[frame.id].document;
            if (doc) {
                if (doc.body) {
                    if ((contentNode = doc.body.firstChild) && /pre/i.test(contentNode.tagName)) {
                        response.responseText = contentNode.innerText;
                    }
                    else if (contentNode = doc.getElementsByTagName('textarea')[0]) {
                        response.responseText = contentNode.value;
                    }
                    else {
                        response.responseText = doc.body.textContent || doc.body.innerText;
                    }
                }
                response.responseXML = doc.XMLDocument || doc;
            }
        } catch (e) {
        }

        me.fireEvent('requestcomplete', me, response, options);

        Ext.callback(options.success, options.scope, [response, options]);
        Ext.callback(options.callback, options.scope, [options, true, response]);

        setTimeout(function() {
            Ext.removeNode(frame);
        }, 100);
    },

 在这个方法中我注意到

if ((contentNode = doc.body.firstChild) && /pre/i.test(contentNode.tagName)) {
                        response.responseText = contentNode.innerText;
                    }

 于是我又在调试的过程中去查看response的信息,发现在firefox中doc.body.firstChild没有innerText这个属性而是一个innerHTML的属性,并且它的值刚好是我在后台想要抛过来的信息,内容大概是{success:"true",data:"",errorMsg:"",dataMsg:""}. 于是我猜我找到解决此问题的办法了.

  • 解决问题

于是我果断的将上段的代码改成

if ((contentNode = doc.body.firstChild) && /pre/i.test(contentNode.tagName)) {
                        response.responseText = contentNode.innerText||contentNode.innerHTML;
                    }

 将修改后的ext-all-debug.js文件覆盖原来的文件,重新编译重新部署重启服务器,并默默的祈祷能解决这个问题.打开页面,点选要上传的文件,提交............ok,久违的熟悉的画面终于出现了.

几个小时的努力终于有点点成果了.

你可能感兴趣的:(Ajax,上传文件,ExtJs,firefox,dosubmit)