ajax非同步請求302

来源:http://www.cnblogs.com/52XF/archive/2017/12/20/post302.html
-Advertisement-
Play Games

我們知道,只有請求成功ajax才會進行回調處理,具體狀態碼為 status >= 200 && status < 300 || status 304; 這一點通過查看JQuery的源碼就可以證實。 舉個例子來說明,用ajax來實現重定向,ajax非同步請求A,A內部重定向到B。 思考: Q1:ajax ...


  我們知道,只有請求成功ajax才會進行回調處理,具體狀態碼為 status >= 200 && status < 300 || status === 304; 這一點通過查看JQuery的源碼就可以證實。

// Cache response headers
responseHeadersString = headers || "";

// Set readyState
jqXHR.readyState = status > 0 ? 4 : 0;

// Determine if successful
isSuccess = status >= 200 && status < 300 || status === 304;//確定請求是否成功.

// Get response data
if ( responses ) {
    response = ajaxHandleResponses( s, jqXHR, responses );
}

// Convert no matter what (that way responseXXX fields are always set)
response = ajaxConvert( s, response, jqXHR, isSuccess );

// If successful, handle type chaining
if ( isSuccess ) {

    // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
    if ( s.ifModified ) {
        modified = jqXHR.getResponseHeader("Last-Modified");
        if ( modified ) {
            jQuery.lastModified[ cacheURL ] = modified;
        }
        modified = jqXHR.getResponseHeader("etag");
        if ( modified ) {
            jQuery.etag[ cacheURL ] = modified;
        }
    }

    // if no content
    if ( status === 204 || s.type === "HEAD" ) {
        statusText = "nocontent";

    // if not modified
    } else if ( status === 304 ) {
        statusText = "notmodified";

    // If we have data, let's convert it
    } else {
        statusText = response.state;
        success = response.data;
        error = response.error;
        isSuccess = !error;
    }
} else {
    // We extract error from statusText
    // then normalize statusText and status for non-aborts
    error = statusText;
    if ( status || !statusText ) {
        statusText = "error";
        if ( status < 0 ) {
            status = 0;
        }
    }
}

  舉個例子來說明,用ajax來實現重定向,ajax非同步請求A,A內部重定向到B。

  思考:

  Q1:ajax回調方法是否會被執行?

  Q2:ajax能否重定向?

var mobile = $("input[name='mobile']").val();
$.post("/recharge/pay", {mobile:mobile}, function(backData) {
    alert("執行回調");
    alert(backData);
}).complete(function(xhr) {
    alert("請求狀態碼:"+xhr.status);
});
@RequestMapping(value = "/recharge/m{mobile}",method = RequestMethod.GET)
public String rechargeB(@PathVariable String mobile, ModelMap model){
    model.put("mobile",mobile);
    return "user/recharge";
}

@RequestMapping(value = "/recharge/pay",method = RequestMethod.POST)
public String rechargeA(String mobile){
    String rechargeUrl = "/recharge/m19012345678";
    return "redirect:"+rechargeUrl;
}

  測試之後發現,回調方法能正常執行,返回的狀態碼也是200,這裡具體是怎麼執行的呢?首先,ajax post 請求到/recharge/pay之後,A方法內部進行重定向,這個時候返回的狀態碼應該是302;其次,A重定向到B之後,執行完成返回的狀態碼應該是200;回調方法是在B執行完才執行的。通過谷歌瀏覽器的Network可證實。

  這個問題可參考stackoverflow上的一個回答。

You can't handle redirects with XHR callbacks because the browser takes care of them automatically. You will only get back what at the redirected location.

  原來,當伺服器將302響應發給瀏覽器時,瀏覽器並不是直接進行ajax回調處理,而是先執行302重定向——從Response Headers中讀取Location信息,然後向Location中的Url發出請求,在收到這個請求的響應後才會進行ajax回調處理。大致流程如下:

ajax -> browser -> server -> 302 -> browser(redirect) -> server -> browser -> ajax callback

而在我們的測試程式中,由於302返回的重定向URL在伺服器上有相應的處理程式,所以在ajax回調函數中得到的狀態碼是200。

所以,如果你想在ajax請求中根據302響應通過location.href進行重定向是不可行的。

  在測試的時候註意一下,如果你指定了ajax的第4個參數dataType(預期伺服器返回的數據類型),可能不會觸發回調方法,因為這裡會先執行重定向,也就是說,重定向後的內容會作為ajax的介面內容來響應,調試時你也能看見backData的內容不是json字元串,而是重定向到B頁面的html字元串。其實這個測試示例的流程本身就存在著問題,ajax請求的地址應該只返回數據,而不是重定向。

  另外需要註意的一點是,get、post就是在ajax的基礎上進行封裝的,只封裝了success,並沒有封裝error方法,所以,只要請求返回的狀態碼不是200-300,就不會走回調方法,見源碼。

jQuery.each( [ "get", "post" ], function( i, method ) {
    jQuery[ method ] = function( url, data, callback, type ) {
        // shift arguments if data argument was omitted
        if ( jQuery.isFunction( data ) ) {
            type = type || callback;
            callback = data;
            data = undefined;
        }

        return jQuery.ajax({
            url: url,
            type: method,
            dataType: type,
            data: data,
            success: callback //只封裝了success方法,沒有error。
        });
    };
});

 

總結:

  1、ajax主要用於非同步請求數據,而不是重定向,它只負責獲取數據或處理結果;

  2、只有狀態碼 status>=200 && status<300 || status==304 ,才被視為success,才會走success的回調方法;

  3、post、get 只封裝了ajax的success方法。

 

參考文獻

 


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

-Advertisement-
Play Games
更多相關文章
  • 先開一篇,以後再補充。。。 1、如果一個 tableView 對應多個 dataSource 。那麼要考慮,點擊/滑動 切換時,請求返回的數據,是否是當前 “功能選中”的位置。 對比請求前後的欄位、狀態若不是,1)、可丟棄。 2)、可刷新該狀態對應的 dataSource 數組(有的話),下次切換, ...
  • 下午001-動態操作元素 創建元素:$('標簽字元串')添加元素:append(),appendTo():追加子元素prepend(),prependTo():前加子元素after(),insertAfter():後加兄弟元素before(),insertBefore():前加兄弟元素動態刪除元素e ...
  • 什麼也不想說 對應的WEB頁面 ...
  • css的註釋 /*.......*/ 直接在html代碼中寫css <p style="color: rebeccapurple;font-size: 18px">Hao</p> css代碼寫在當前文件中 <head> <meta charset="UTF-8"> <title>Title</tit ...
  • 解決掉了最頭疼的DirectoryWatcher內部實現,這一節可以結束NodeWatchFileSystem模塊。 關於watch的應用場景,仔細思考了下,這不就是熱重載的核心嘛。 首先是監視文件,觸發文件change事件後收集變動文件信息,重新進行打包,更新JS後觸發頁面重新渲染,perfect ...
  • 第1部分 概要 第1章 JavaScript概要:JavaScript的發展歷史、瀏覽器的JavaScript引擎、源代碼壓縮 ...
  • HTML是個什麼鬼? 前端開發人員要想和瀏覽器溝通,就要用到瀏覽器才能夠識別的語言(HTML超文本標記語言),所以他是一門瀏覽器能夠識別的語言。是一種由標簽組成的超文本標記語言,而非編程語言。一個html文檔就是一個網頁。 什麼是html標簽呢? HTML標記標簽通常被稱為HEML標簽,他是由尖括弧 ...
  • $(function(){ $.fn.autoHeight = function(){ function autoHeight(elem){ elem.style.height = 'auto'; elem.scrollTop = 0; //防抖動 elem.style.height = elem. ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...