遇到这样一种状况,打开网页两个窗口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异步请求中,服务器不该该出现直接跳转。异步