關於jquery中ajax請求在ie中報No Transport錯誤解決流程

来源:http://www.cnblogs.com/blanche91/archive/2017/05/08/6825861.html
-Advertisement-
Play Games

首先背景就是測試同學發現我們的網頁在ie9中展示不正確,實際是所有非同步的介面都沒有執行。然後我就開始了苦逼的排查過程。我們所有非同步介面都是使用jQuery的ajax方法發出的,使用的jquery版本是1.11.0。 我最先定位到的是ajax方法返回status=0,statusText=No Tra ...


首先背景就是測試同學發現我們的網頁在ie9中展示不正確,實際是所有非同步的介面都沒有執行。然後我就開始了苦逼的排查過程。我們所有非同步介面都是使用jQuery的ajax方法發出的,使用的jquery版本是1.11.0。

我最先定位到的是ajax方法返回status=0,statusText=No Transport。然後開始了我的查找問題之旅,我在網上所查出的資料都說這個是由於跨域造成的,加上$.support.cros=true就可以。但實際我們項目訪問的介面並不屬於跨域。所以雖然加上這個屬性可以解決問題,但並沒有找到根源。

於是我開始看jquery的源碼,先定位了發生錯誤的代碼段,先貼上報錯點:

 1 // Get transport
 2         transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
 3 
 4         // If no transport, we auto-abort
 5         if ( !transport ) {
 6             done( -1, "No Transport" );
 7         } else {
 8             jqXHR.readyState = 1;
 9 
10             // Send global event
11             if ( fireGlobals ) {
12                 globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
13             }
14             // Timeout
15             if ( s.async && s.timeout > 0 ) {
16                 timeoutTimer = setTimeout(function() {
17                     jqXHR.abort("timeout");
18                 }, s.timeout );
19             }
20 
21             try {
22                 state = 1;
23                 transport.send( requestHeaders, done );
24             } catch ( e ) {
25                 // Propagate exception as error if not done
26                 if ( state < 2 ) {
27                     done( -1, e );
28                 // Simply rethrow otherwise
29                 } else {
30                     throw e;
31                 }
32             }
33         }

 

此處transport =false。剛開始並不能完全看懂jquery源碼,於是請教了我們公司的一位大神,在大神的指導下我開始排查為何transport =false。經過萬能的斷點調試,發現是由於下列代碼中的options.crossDomain = true導致的不能進入此段正確發送請求的關鍵代碼(具體的代碼作用不作分析)。到此終於定位罪魁禍首是最初我為了在html頁面可以直接訪問api伺服器而增加的crossDomain=true的設置(因為html和api伺服器屬於不同功能變數名稱)。(此處並未結束,請繼續往下看)

  1 // Determine support properties
  2 support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported );
  3 xhrSupported = support.ajax = !!xhrSupported;
  4 
  5 // Create transport if the browser can provide an xhr
  6 if ( xhrSupported ) {
  7 
  8     jQuery.ajaxTransport(function( options ) {
  9         // Cross domain only allowed if supported through XMLHttpRequest
 10         if ( !options.crossDomain || support.cors ) {
 11 
 12             var callback;
 13 
 14             return {
 15                 send: function( headers, complete ) {
 16                     var i,
 17                         xhr = options.xhr(),
 18                         id = ++xhrId;
 19 
 20                     // Open the socket
 21                     xhr.open( options.type, options.url, options.async, options.username, options.password );
 22 
 23                     // Apply custom fields if provided
 24                     if ( options.xhrFields ) {
 25                         for ( i in options.xhrFields ) {
 26                             xhr[ i ] = options.xhrFields[ i ];
 27                         }
 28                     }
 29 
 30                     // Override mime type if needed
 31                     if ( options.mimeType && xhr.overrideMimeType ) {
 32                         xhr.overrideMimeType( options.mimeType );
 33                     }
 34 
 35                     // X-Requested-With header
 36                     // For cross-domain requests, seeing as conditions for a preflight are
 37                     // akin to a jigsaw puzzle, we simply never set it to be sure.
 38                     // (it can always be set on a per-request basis or even using ajaxSetup)
 39                     // For same-domain requests, won't change header if already provided.
 40                     if ( !options.crossDomain && !headers["X-Requested-With"] ) {
 41                         headers["X-Requested-With"] = "XMLHttpRequest";
 42                     }
 43 
 44                     // Set headers
 45                     for ( i in headers ) {
 46                         // Support: IE<9
 47                         // IE's ActiveXObject throws a 'Type Mismatch' exception when setting
 48                         // request header to a null-value.
 49                         //
 50                         // To keep consistent with other XHR implementations, cast the value
 51                         // to string and ignore `undefined`.
 52                         if ( headers[ i ] !== undefined ) {
 53                             xhr.setRequestHeader( i, headers[ i ] + "" );
 54                         }
 55                     }
 56 
 57                     // Do send the request
 58                     // This may raise an exception which is actually
 59                     // handled in jQuery.ajax (so no try/catch here)
 60                     xhr.send( ( options.hasContent && options.data ) || null );
 61 
 62                     // Listener
 63                     callback = function( _, isAbort ) {
 64                         var status, statusText, responses;
 65 
 66                         // Was never called and is aborted or complete
 67                         if ( callback && ( isAbort || xhr.readyState === 4 ) ) {
 68                             // Clean up
 69                             delete xhrCallbacks[ id ];
 70                             callback = undefined;
 71                             xhr.onreadystatechange = jQuery.noop;
 72 
 73                             // Abort manually if needed
 74                             if ( isAbort ) {
 75                                 if ( xhr.readyState !== 4 ) {
 76                                     xhr.abort();
 77                                 }
 78                             } else {
 79                                 responses = {};
 80                                 status = xhr.status;
 81 
 82                                 // Support: IE<10
 83                                 // Accessing binary-data responseText throws an exception
 84                                 // (#11426)
 85                                 if ( typeof xhr.responseText === "string" ) {
 86                                     responses.text = xhr.responseText;
 87                                 }
 88 
 89                                 // Firefox throws an exception when accessing
 90                                 // statusText for faulty cross-domain requests
 91                                 try {
 92                                     statusText = xhr.statusText;
 93                                 } catch( e ) {
 94                                     // We normalize with Webkit giving an empty statusText
 95                                     statusText = "";
 96                                 }
 97 
 98                                 // Filter status for non standard behaviors
 99 
100                                 // If the request is local and we have data: assume a success
101                                 // (success with no data won't get notified, that's the best we
102                                 // can do given current implementations)
103                                 if ( !status && options.isLocal && !options.crossDomain ) {
104                                     status = responses.text ? 200 : 404;
105                                 // IE - #1450: sometimes returns 1223 when it should be 204
106                                 } else if ( status === 1223 ) {
107                                     status = 204;
108                                 }
109                             }
110                         }
111 
112                         // Call complete if needed
113                         if ( responses ) {
114                             complete( status, statusText, responses, xhr.getAllResponseHeaders() );
115                         }
116                     };
117 
118                     if ( !options.async ) {
119                         // if we're in sync mode we fire the callback
120                         callback();
121                     } else if ( xhr.readyState === 4 ) {
122                         // (IE6 & IE7) if it's in cache and has been
123                         // retrieved directly we need to fire the callback
124                         setTimeout( callback );
125                     } else {
126                         // Add to the list of active xhr callbacks
127                         xhr.onreadystatechange = xhrCallbacks[ id ] = callback;
128                     }
129                 },
130 
131                 abort: function() {
132                     if ( callback ) {
133                         callback( undefined, true );
134                     }
135                 }
136             };
137         }
138     });
139 }

 

到此本來應該結束了,但並沒有,雖然我增加了crossDomain=true的設置,但為何其他瀏覽器可以正常訪問,而ie9不行呢。我繼續調試代碼,最終發現其他瀏覽器上述代碼中support.cors = true,而ie9下這個屬性等於false。從上述代碼中也可以看到,這個屬性的判斷來自於support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported ),其中xhrSupported= new window.XMLHttpRequest(),ie9中XMLHttpRequest沒有withCredentials屬性。也就是說這個問題是由於我的亂用屬性加上各瀏覽器相容性問題而導致的。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 軟體工程第二次作業——結對編程 ================================ 團隊 學號:1500802014;姓名:孟祥磊;博客地址: "http://www.cnblogs.com/MXLei1/" 學號:1500802013;姓名:劉哲乾;博客地址: "http://www ...
  • 今天在下載一個比較大的項目,經常shasum check failed,太煩了,於是想切淘寶源,分別嘗試nrm切換和傳遞 registry,結果都出現Unexpected end of JSON input錯誤。這是比較奇怪的,看起來是JSON數據沒有傳完。結合以前SwitchyOmega走priv ...
  • 1.圖片 <img / > 圖片的格式: 1.1BMP 占用空間大,顏色豐富。 1.2JPEG 有損壓縮,占用空間較小。 1.3GIF 多幀動圖,支持透明色。 1.4PNG 無損壓縮,點陣圖(由無數小點組成)支持透明色/半透明色。 <img /> 屬性: src="PATH” PATH:圖片的所在路徑 ...
  • 這是我幾個月之前的項目作品,花了相當的時間去完善。博客人氣不高,但拿代碼的人不少,所以一直處於保密狀態。沒有公開代碼。但如果對你有幫助,並能提出指導意見的,我將十分感謝。 IFE前端2015春季 任務3 綜合練習 任務描述 參考 "設計稿" 實現一個簡單的個人任務管理系統:如下圖 " " 任務需求描 ...
  • 現在部分瀏覽器已支持自定義滾動條,成了設計師和完美主義者的救星。 新版上線後,設計師又提了個新需求:把導航欄右側的滾動條,在不滾動時隱藏掉(同時還發了個小視頻表示效果)。就是下圖中右側的粗線: 在mac系統下測試了Chrome/Safari/Firefox瀏覽器,發現這些系統在預設情況下,不滾動時滾 ...
  • <!-- pre{ width: 900px; color:blue; font-weight: bolder; } --> 盒子模型 1.background 1.1 background-color background-image: url(""); background-repeat bac ...
  • 有空時候把一些常見可能不是每個人都知道的css小細節總結了下,共勉。 1.line-height 眾多周知,line-height是行高的意思,我們時常會使用類似line-height:24px;這樣的代碼來設置絕對的行高。但是當我們的需求改變,字體大小變動的時候,可能我們還需要再次改動行高,那麼現 ...
  • express + randomjson 模擬後端服務,前端伺服器(比如webpack, nigix等)將請求代理到該伺服器地址即可實現前後端分離 ...
一周排行
    -Advertisement-
    Play Games
  • 前言 本文介紹一款使用 C# 與 WPF 開發的音頻播放器,其界面簡潔大方,操作體驗流暢。該播放器支持多種音頻格式(如 MP4、WMA、OGG、FLAC 等),並具備標記、實時歌詞顯示等功能。 另外,還支持換膚及多語言(中英文)切換。核心音頻處理採用 FFmpeg 組件,獲得了廣泛認可,目前 Git ...
  • OAuth2.0授權驗證-gitee授權碼模式 本文主要介紹如何筆者自己是如何使用gitee提供的OAuth2.0協議完成授權驗證並登錄到自己的系統,完整模式如圖 1、創建應用 打開gitee個人中心->第三方應用->創建應用 創建應用後在我的應用界面,查看已創建應用的Client ID和Clien ...
  • 解決了這個問題:《winForm下,fastReport.net 從.net framework 升級到.net5遇到的錯誤“Operation is not supported on this platform.”》 本文內容轉載自:https://www.fcnsoft.com/Home/Sho ...
  • 國內文章 WPF 從裸 Win 32 的 WM_Pointer 消息獲取觸摸點繪製筆跡 https://www.cnblogs.com/lindexi/p/18390983 本文將告訴大家如何在 WPF 裡面,接收裸 Win 32 的 WM_Pointer 消息,從消息裡面獲取觸摸點信息,使用觸摸點 ...
  • 前言 給大家推薦一個專為新零售快消行業打造了一套高效的進銷存管理系統。 系統不僅具備強大的庫存管理功能,還集成了高性能的輕量級 POS 解決方案,確保頁面載入速度極快,提供良好的用戶體驗。 項目介紹 Dorisoy.POS 是一款基於 .NET 7 和 Angular 4 開發的新零售快消進銷存管理 ...
  • ABP CLI常用的代碼分享 一、確保環境配置正確 安裝.NET CLI: ABP CLI是基於.NET Core或.NET 5/6/7等更高版本構建的,因此首先需要在你的開發環境中安裝.NET CLI。這可以通過訪問Microsoft官網下載並安裝相應版本的.NET SDK來實現。 安裝ABP ...
  • 問題 問題是這樣的:第三方的webapi,需要先調用登陸介面獲取Cookie,訪問其它介面時攜帶Cookie信息。 但使用HttpClient類調用登陸介面,返回的Headers中沒有找到Cookie信息。 分析 首先,使用Postman測試該登陸介面,正常返回Cookie信息,說明是HttpCli ...
  • 國內文章 關於.NET在中國為什麼工資低的分析 https://www.cnblogs.com/thinkingmore/p/18406244 .NET在中國開發者的薪資偏低,主要因市場需求、技術棧選擇和企業文化等因素所致。歷史上,.NET曾因微軟的閉源策略發展受限,儘管後來推出了跨平臺的.NET ...
  • 在WPF開發應用中,動畫不僅可以引起用戶的註意與興趣,而且還使軟體更加便於使用。前面幾篇文章講解了畫筆(Brush),形狀(Shape),幾何圖形(Geometry),變換(Transform)等相關內容,今天繼續講解動畫相關內容和知識點,僅供學習分享使用,如有不足之處,還請指正。 ...
  • 什麼是委托? 委托可以說是把一個方法代入另一個方法執行,相當於指向函數的指針;事件就相當於保存委托的數組; 1.實例化委托的方式: 方式1:通過new創建實例: public delegate void ShowDelegate(); 或者 public delegate string ShowDe ...