关于jquery中ajax请求在ie中报No Transport错误解决流程
来源:互联网 发布:mac怎么升级 编辑:程序博客网 时间:2024/06/03 20:51
关于jquery中ajax请求在ie中报No Transport错误解决流程
首先背景就是测试同学发现我们的网页在ie9中展示不正确,实际是所有异步的接口都没有执行。然后我就开始了苦逼的排查过程。我们所有异步接口都是使用jquery的ajax方法发出的,使用的jquery版本是1.11.0。
我最先定位到的是ajax方法返回status=0,statusText=No Transport。然后开始了我的查找问题之旅,我在网上所查出的资料都说这个是由于跨域造成的,加上$.support.cros=true
就可以。但实际我们项目访问的接口并不属于跨域。所以虽然加上这个属性可以解决问题,但并没有找到根源。
于是我开始看jquery的源码,先定位了发生错误的代码段,先贴上报错点:
// Get transport transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR ); // If no transport, we auto-abort if ( !transport ) { done( -1, "No Transport" ); } else { jqXHR.readyState = 1; // Send global event if ( fireGlobals ) { globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] ); } // Timeout if ( s.async && s.timeout > 0 ) { timeoutTimer = setTimeout(function() { jqXHR.abort("timeout"); }, s.timeout ); } try { state = 1; transport.send( requestHeaders, done ); } catch ( e ) { // Propagate exception as error if not done if ( state < 2 ) { done( -1, e ); // Simply rethrow otherwise } else { throw e; } } }
此处transport =false。刚开始并不能完全看懂jquery源码,于是请教了我们公司的一位大神,在大神的指导下我开始排查为何transport =false。经过万能的断点调试,发现是由于下列代码中的options.crossDomain = true
导致的不能进入此段正确发送请求的关键代码(具体的代码作用不作分析)。到此终于定位罪魁祸首是最初我为了在html页面可以直接访问api服务器而增加的crossDomain=true
的设置(因为html和api服务器属于不同域名)。(此处并未结束,请继续往下看)
// Determine support propertiessupport.cors = !!xhrSupported && ( "withCredentials" in xhrSupported );xhrSupported = support.ajax = !!xhrSupported;// Create transport if the browser can provide an xhrif ( xhrSupported ) { jQuery.ajaxTransport(function( options ) { // Cross domain only allowed if supported through XMLHttpRequest if ( !options.crossDomain || support.cors ) { var callback; return { send: function( headers, complete ) { var i, xhr = options.xhr(), id = ++xhrId; // Open the socket xhr.open( options.type, options.url, options.async, options.username, options.password ); // Apply custom fields if provided if ( options.xhrFields ) { for ( i in options.xhrFields ) { xhr[ i ] = options.xhrFields[ i ]; } } // Override mime type if needed if ( options.mimeType && xhr.overrideMimeType ) { xhr.overrideMimeType( options.mimeType ); } // X-Requested-With header // For cross-domain requests, seeing as conditions for a preflight are // akin to a jigsaw puzzle, we simply never set it to be sure. // (it can always be set on a per-request basis or even using ajaxSetup) // For same-domain requests, won't change header if already provided. if ( !options.crossDomain && !headers["X-Requested-With"] ) { headers["X-Requested-With"] = "XMLHttpRequest"; } // Set headers for ( i in headers ) { // Support: IE<9 // IE's ActiveXObject throws a 'Type Mismatch' exception when setting // request header to a null-value. // // To keep consistent with other XHR implementations, cast the value // to string and ignore `undefined`. if ( headers[ i ] !== undefined ) { xhr.setRequestHeader( i, headers[ i ] + "" ); } } // Do send the request // This may raise an exception which is actually // handled in jQuery.ajax (so no try/catch here) xhr.send( ( options.hasContent && options.data ) || null ); // Listener callback = function( _, isAbort ) { var status, statusText, responses; // Was never called and is aborted or complete if ( callback && ( isAbort || xhr.readyState === 4 ) ) { // Clean up delete xhrCallbacks[ id ]; callback = undefined; xhr.onreadystatechange = jQuery.noop; // Abort manually if needed if ( isAbort ) { if ( xhr.readyState !== 4 ) { xhr.abort(); } } else { responses = {}; status = xhr.status; // Support: IE<10 // Accessing binary-data responseText throws an exception // (#11426) if ( typeof xhr.responseText === "string" ) { responses.text = xhr.responseText; } // Firefox throws an exception when accessing // statusText for faulty cross-domain requests try { statusText = xhr.statusText; } catch( e ) { // We normalize with Webkit giving an empty statusText statusText = ""; } // Filter status for non standard behaviors // If the request is local and we have data: assume a success // (success with no data won't get notified, that's the best we // can do given current implementations) if ( !status && options.isLocal && !options.crossDomain ) { status = responses.text ? 200 : 404; // IE - #1450: sometimes returns 1223 when it should be 204 } else if ( status === 1223 ) { status = 204; } } } // Call complete if needed if ( responses ) { complete( status, statusText, responses, xhr.getAllResponseHeaders() ); } }; if ( !options.async ) { // if we're in sync mode we fire the callback callback(); } else if ( xhr.readyState === 4 ) { // (IE6 & IE7) if it's in cache and has been // retrieved directly we need to fire the callback setTimeout( callback ); } else { // Add to the list of active xhr callbacks xhr.onreadystatechange = xhrCallbacks[ id ] = callback; } }, abort: function() { if ( callback ) { callback( undefined, true ); } } }; } });}
到此本来应该结束了,但并没有,虽然我增加了crossDomain=true
的设置,但为何其他浏览器可以正常访问,而ie9不行呢。我继续调试代码,最终发现其他浏览器上述代码中support.cors = true
,而ie9下这个属性等于false。从上述代码中也可以看到,这个属性的判断来自于support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported )
,其中xhrSupported= new window.XMLHttpRequest()
,ie9中XMLHttpRequest没有withCredentials属性。也就是说这个问题是由于我的乱用属性加上各浏览器兼容性问题而导致的。
- 关于jquery中ajax请求在ie中报No Transport错误解决流程
- $.ajax请求数据 IE报 no transport 或拒绝访问
- jQuery .Ajax() 方法在IE浏览器返回No Transport错误原因?
- jQuery .Ajax() 方法在IE浏览器返回No Transport错误原因?
- jQuery .Ajax() 方法在IE浏览器返回No Transport错误原因?
- 【JQuery-01】JQuery-Ajax请求在IE中清除缓存
- 在ie中关于ajax请求获得数据缓存问题的解决办法
- 关于框架(spring)中ajax请求报406错误的情况
- JQuery中ajax请求
- Jquery中ajax请求
- 解决在IE tbody中使用innerHTML报运行时错误问题
- 关于Jquery Ajax 在IE中异步调用失败的解决办法
- ie9 jquery.ajax 返回异常No Transport
- Ext 在ie中报 ext-all.js 错误,解决办法
- 解决ajax时出现No Transport
- 解决IE6中ajax ‘aborted’错误请求中断
- 解决Ajax在IE浏览器中缓存问题
- 关于jquery中ajax
- 实现数字从零动态跳动到(规定)最大值或原始值
- 谷歌浏览器调试javascript方法
- 去掉列表中一行最后一个外边距
- Calendar设置下一分钟
- 在jsp编程中,用get提交表单提交正常,而用post方式出现中文乱码-问题
- 关于jquery中ajax请求在ie中报No Transport错误解决流程
- shell-awk
- 在Maven+Spring项目中使用Node.js的Gulp进行前端自动化构建
- 皇后问题(棋盘问题)
- C++内存分配
- 基于Thrift实现跨语言服务
- 一起艳恶学习百度地图api(三)
- UNIX再学习 -- 函数abort
- composer安装