1. 程式人生 > >ajax異步請求302分析

ajax異步請求302分析

取數據 cep ted tag The 和我 增刪改 我們 頁面跳轉

1.前言

遇到這樣一種情況,打開網頁兩個窗口a,b(都是已經登錄授權的),在a頁面中退出登錄,然後在b頁面執行增刪改查,這個時候因為授權原因,b頁面後端的請求肯定出現異常(對這個異常的處理,進行內部跳轉處理),b頁面中的ajax請求的回調中就會出現問題,今天遇到了,有種恍然大悟的感覺,打開以前公司的網站發現全都沒做任何處理......
沒遇到過錯誤,永遠不知道錯誤會什麽時候出現。

2.問題:在ajax異步請求中,如果服務端出現內部跳轉,如何在回調中處理

我們先來看這樣一個簡單的ajax異步請求

$.ajax({
    url: ‘/User/Add‘,
    type: ‘post‘,
    data: data,
    success:function(data,status)
    {
        console.log(‘data:‘+data);
        console.log(‘status:‘+status);
    },
    complete: function(xhr){
        console.log(xhr.status);
    },
    error: function (xhr) {
        debugger;
        console.log(xhr.status);
    }
});    

後端處理時,拋出異常,出現了內部重定向
稍微簡單解釋一下,用的mvc,加了一個全局的異常,在Add方法中拋出異常,在OnException會進行捕獲到這個異常,代碼很簡單也比較典型。

    public class GlobalHandlerErrorAttribute : HandleErrorAttribute
    {
        public override void OnException(ExceptionContext actionExecutedContext)
        {
                actionExecutedContext.HttpContext.Response.Redirect("/User/Login");
        }
    }
        public ActionResult Add(UserModel model)
        {
            throw new HttpException("un authorize");
        }

結果是什麽?
回調中會進入到success方法,輸入data:是Login頁面的整個內容,status:success ,完成回調complete中輸出的是200,並不會和我們預期進入到error方法中來。

3.原因

用一句話來形容上面的問題就是:ajax異步請求A,A內部重定向到B。
得到的答案是:
1.ajax回調方法success中得到是B頁面內容
2.ajax是用於處理數據的,並不會按照服務器的內部跳轉而進行跳轉,如果要跳轉可以根據回調中信息進行跳轉。
3.ajax請求,後端出現跳轉,不會進入到error回調中的,當然回調中跳轉到一個不存在的頁面,那是會進入error方法中來的。
當服務器將302響應發給瀏覽器時,瀏覽器並不是直接進行ajax回調處理,而是先執行302重定向,回調success中獲取的內容是重定向後的頁面。
jquery源碼中是這樣寫的,http狀態碼200-300或者304才會進入success回調的
isSuccess = status >= 200 && status < 300 || status === 304;//確定請求是否成功

// 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;
        }
    }
}

4.如何處理ajax異步請求後端跳轉

ajax異步請求數據,後端出現跳轉,這個時候說明程序出現了異常,可以捕獲到這個異常,返回給前端,前端ajax根據返回信息,進行判斷,給出正確的提示。
在全局異常中可以這樣返回給前端

            actionExecutedContext.Result = new JsonResult()
            {
                Data = new ViewModels.Web.Response.JsonResultModel()
                {
                    code = 302,
                    message = "具體的錯誤信息",
                    success = false
                }
            };

前端可以進行判斷,給出相應的提示信息或者直接跳轉

$.ajax({
    url: ‘/User/Add‘,
    type: ‘post‘,
    data: data,
    success:function(data,status)
    {
      if(code==302)
      {
        alert(data.message);
        //location.href=‘/User/Login‘ 也可以在返回類型加一個字段location,那就直接location.href=‘/User/Login/‘
      }
        console.log(‘data:‘+data);
        console.log(‘status:‘+status);
    },
    complete: function(xhr){
        console.log(xhr.status);
    },
    error: function (xhr) {
        debugger;
        console.log(xhr.status);
    }
});    

5.總結

1.ajax success回調處理,具體狀態碼為 status >= 200 && status < 300 || status === 304
2.ajax是用於異步獲取數據的,並不是用於頁面跳轉
3.mvc中,如果給某些方法設置權限,就會導致權限驗證,從而產生跳轉登陸界,應該加上全局的異常捕獲,既然是ajax請求,說明請求數據出現異常,應該給出相應的錯誤信息提示,這個提示也應該在服務器進行確定,前端負責展示。
4.ajax異步請求中,服務器不應該出現直接跳轉。

ajax異步請求302分析