遇到這樣一種狀況,打開網頁兩個窗口a,b(都是已經登陸受權的),在a頁面中退出登陸,而後在b頁面執行增刪改查,這個時候由於受權緣由,b頁面後端的請求確定出現異常(對這個異常的處理,進行內部跳轉處理),b頁面中的ajax請求的回調中就會出現問題,今天遇到了,有種恍然大悟的感受,打開之前公司的網站發現全都沒作任何處理......
沒遇到過錯誤,永遠不知道錯誤會何時出現。前端
咱們先來看這樣一個簡單的ajax異步請求jquery
$.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會進行捕獲到這個異常,代碼很簡單也比較典型。ajax
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方法中來。後端
用一句話來形容上面的問題就是: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; } } }
ajax異步請求數據,後端出現跳轉,這個時候說明程序出現了異常,能夠捕獲到這個異常,返回給前端,前端ajax根據返回信息,進行判斷,給出正確的提示。
在全局異常中能夠這樣返回給前端服務器
actionExecutedContext.Result = new JsonResult() { Data = new ViewModels.Web.Response.JsonResultModel() { code = 302, message = "具體的錯誤信息", success = false } };
前端能夠進行判斷,給出相應的提示信息或者直接跳轉mvc
$.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); } });
1.ajax success回調處理,具體狀態碼爲 status >= 200 && status < 300 || status === 304
2.ajax是用於異步獲取數據的,並非用於頁面跳轉
3.mvc中,若是給某些方法設置權限,就會致使權限驗證,從而產生跳轉登錄界,應該加上全局的異常捕獲,既然是ajax請求,說明請求數據出現異常,應該給出相應的錯誤信息提示,這個提示也應該在服務器進行肯定,前端負責展現。
4.ajax異步請求中,服務器不該該出現直接跳轉。異步