• INVALID_STATE_ERR: DOM Exception 11


    这是在Chrome中提示的错误

    IE中提示为:完成该操作所需的数据还不可使用。

    出现场景:

    在使用jQuery的ajax且网络很慢、设置了timeout的情况下,直接不判断ajax的readyState而直接取responseText将出会错(此时xhr对象可能只有两个属性可用:

    responseXML、readyState)。

    例如如果使用Ext+jQuery进行的开发中,ext-jQuery-adapter-debug.js中的代码有:

    Ext.lib.Ajax = function(){
        var createComplete = function(cb){
             return function(xhr, status){
                if((status == 'error' || status == 'timeout') && cb.failure){
                    cb.failure.call(cb.scope||window, createResponse(cb, xhr));
                }else if(cb.success){
                    cb.success.call(cb.scope||window, createResponse(cb, xhr));
                }
             };
        };
        
        var createResponse = function(cb, xhr){
            var headerObj = {},
                headerStr,              
                t,
                s;
    
            try {
                headerStr = xhr.getAllResponseHeaders();   
                Ext.each(headerStr.replace(/\r\n/g, '\n').split('\n'), function(v){
                    t = v.indexOf(':');
                    if(t >= 0){
                        s = v.substr(0, t).toLowerCase();
                        if(v.charAt(t + 1) == ' '){
                            ++t;
                        }
                        headerObj[s] = v.substr(t + 1);
                    }
                });
            } catch(e) {}
            
            return {
                responseText: xhr.responseText,
                responseXML : xhr.responseXML,
                argument: cb.argument,
                status: xhr.status,
                statusText: xhr.statusText,
                getResponseHeader : function(header){return headerObj[header.toLowerCase()];},
                getAllResponseHeaders : function(){return headerStr}
            };
        };
        return {
            request : function(method, uri, cb, data, options){
                var o = {
                    type: method,
                    url: uri,
                    data: data,
                    timeout: cb.timeout,
                    complete: createComplete(cb)
                };
    
                if(options){
                    var hs = options.headers;
                    if(options.xmlData){
                        o.data = options.xmlData;
                        o.processData = false;
                        o.type = (method ? method : (options.method ? options.method : 'POST'));
                        if (!hs || !hs['Content-Type']){
                            o.contentType = 'text/xml';
                        }
                    }else if(options.jsonData){
                        o.data = typeof options.jsonData == 'object' ? Ext.encode(options.jsonData) : options.jsonData;
                        o.processData = false;
                        o.type = (method ? method : (options.method ? options.method : 'POST'));
                        if (!hs || !hs['Content-Type']){
                            o.contentType = 'application/json';
                        }
                    }
                    if(hs){
                        o.beforeSend = function(xhr){
                            for(var h in hs){
                                if(hs.hasOwnProperty(h)){
                                    xhr.setRequestHeader(h, hs[h]);
                                }
                            }
                        }
                    }
                }
                jQuery.ajax(o);
            },
    
            formRequest : function(form, uri, cb, data, isUpload, sslUri){
                jQuery.ajax({
                    type: Ext.getDom(form).method ||'POST',
                    url: uri,
                    data: jQuery(form).serialize()+(data?'&'+data:''),
                    timeout: cb.timeout,
                    complete: createComplete(cb)
                });
            },
    
            isCallInProgress : function(trans){
                return false;
            },
    
            abort : function(trans){
                return false;
            },
    
            serializeForm : function(form){
                return jQuery(form.dom||form).serialize();
            }
        };
    }();

    在jquery回调的时候,它调用 createResponse方法,而在createResponse方法中并未进行检测。

    jQuery中的ajax并未监听ajax对象的onreadystatechange,而是使用定时器setInterval去检测它的状态readyState或是直接传入timeout将视为请求结束。对使用timeout结束的请求,它调用其abort方法,取消请求。

    // Wait for a response to come back
    var onreadystatechange = function(isTimeout){
    	// The request was aborted, clear the interval and decrement jQuery.active
    	if (xhr.readyState == 0) {
    		if (ival) {
    			// clear poll interval
    			clearInterval(ival);
    			ival = null;
    			// Handle the global AJAX counter
    			if ( s.global && ! --jQuery.active )
    				jQuery.event.trigger( "ajaxStop" );
    		}
    	// The transfer is complete and the data is available, or the request timed out
    	} else if ( !requestDone && xhr && (xhr.readyState == 4 || isTimeout == "timeout") ) {
    		requestDone = true;
    
    		// clear poll interval
    		if (ival) {
    			clearInterval(ival);
    			ival = null;
    		}
    
    		status = isTimeout == "timeout" ? "timeout" :
    			!jQuery.httpSuccess( xhr ) ? "error" :
    			s.ifModified && jQuery.httpNotModified( xhr, s.url ) ? "notmodified" :
    			"success";
    
    		if ( status == "success" ) {
    			// Watch for, and catch, XML document parse errors
    			try {
    				// process the data (runs the xml through httpData regardless of callback)
    				data = jQuery.httpData( xhr, s.dataType, s );
    			} catch(e) {
    				status = "parsererror";
    			}
    		}
    
    		// Make sure that the request was successful or notmodified
    		if ( status == "success" ) {
    			// Cache Last-Modified header, if ifModified mode.
    			var modRes;
    			try {
    				modRes = xhr.getResponseHeader("Last-Modified");
    			} catch(e) {} // swallow exception thrown by FF if header is not available
    
    			if ( s.ifModified && modRes )
    				jQuery.lastModified[s.url] = modRes;
    
    			// JSONP handles its own success callback
    			if ( !jsonp )
    				success();
    		} else
    			jQuery.handleError(s, xhr, status);
    
    		// Fire the complete handlers
    		complete();
    
    		if ( isTimeout )
    			xhr.abort();
    
    		// Stop memory leaks
    		if ( s.async )
    			xhr = null;
    	}
    };
    
    if ( s.async ) {
    	// don't attach the handler to the request, just poll it instead
    	var ival = setInterval(onreadystatechange, 13);
    
    	// Timeout checker
    	if ( s.timeout > 0 )
    		setTimeout(function(){
    			// Check to see if the request is still happening
    			if ( xhr && !requestDone )
    				onreadystatechange( "timeout" );
    		}, s.timeout);
    }
     
     
     
     
    
    

    其中ival类似于系统调用了onreadystatechange方法。

    提示,在使用ajax在进行处理结果的时候,需要先判断它的readyState和status两个值。不然容易出错

  • 相关阅读:
    c#中using System.Runtime.Serialization.Json;不能引用
    VS2013 当前不会命中断点还未为文档加载任何符号
    windows2008 设置会话超时时间
    服务没有及时响应启动或控制请求 1053
    IIS装好了无法访问localhost
    Shiro笔记——简介、 架构分析
    Java 连接使用 Redis
    Java 连接操作 Redis 出现错误
    网络方面的常用命令 & 常用端口介绍
    Redis 配置文件及命令详解
  • 原文地址:https://www.cnblogs.com/meteoric_cry/p/1838507.html
Copyright © 2020-2023  润新知