關於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
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...