我提交了这样的标准$.ajax()
请求:
$.ajax({
type: "GET",
url: myUrl
success: function(data) {
$("#replace").html(data)
},
error: function (data) {
console.warn(data);
}
});
或者通过将处理程序附加到ajax promise回调来完成同样的事情:
$.ajax({
type: "GET",
url: myUrl
})
.done(function(data, status) {
console.log(data);
})
.fail(function(data, status) {
console.warn(status);
});
在这两种情况下,或者在使用$.ajaxError()
handler时,如果返回HTTP状态错误,则会调用错误/失败函数。
在我的ASP.NET MVC项目中,我试图返回正确的 HTTP状态代码,这两者都是出于语义原因并被正确的客户端处理程序捕获。
尝试#1 - 根据this answer的建议,我试图像这样返回HttpStatusCodeResult
:
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
if (filterContext.HttpContext.Request.IsAjaxRequest())
{
filterContext.Result = new HttpStatusCodeResult(HttpStatusCode.Unauthorized, accessResult.AccessDeniedMessage);
filterContext.HttpContext.Response.End();
}
else
{
base.HandleUnauthorizedRequest(filterContext);
}
}
尝试#2 - 或者,根据this answer的建议,我已尝试返回JsonResult
并设置Response.StatusCode
filterContext.HttpContext.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
filterContext.Result = new JsonResult()
{
Data = new { Error = "Unauthorized User" },
JsonRequestBehavior = JsonRequestBehavior.AllowGet
};
filterContext.HttpContext.Response.End();
在这两种情况下,响应仍会以 200 OK
的形式返回Always success on ajax post with HttpResponseMessage 401上的这个问题似乎遇到了同样的错误,但没有提出服务器端解决方案,只是允许OK错误状态代码并抓取响应以确定是否发生了错误
答案 0 :(得分:1)
违规问题确实与Always success on ajax post with HttpResponseMessage 401相同。响应已成功返回,但被重定向到表单登录
X-Responded-JSON: {"status": 401, "headers": {"location":"http:\/\/localhost:50004\/Login?ReturnUrl=%2FClient"}}
虽然这个问题似乎没有建议服务器端解决方案,而只是依赖于解析客户端上的错误状态。 Brock Allen 建议在Using cookie authentication middleware with Web API and 401 response codes的帖子中修改服务器端:
通常在使用cookie身份验证中间件时,当服务器(MVC或WebForms)发出401时,响应将转换为302重定向到登录页面(由CookieAuthenticationOptions上的LoginPath配置)。但是当进行Ajax调用并且响应是401时,将302重定向返回到登录页面是没有意义的。相反,你只是期望返回401响应。不幸的是,这不是我们使用cookie中间件获得的行为 - 响应被更改为200状态代码,其中包含带有消息的JSON响应正文:
{"Message":"Authorization has been denied for this request."}
我不确定此功能的要求是什么。要改变它,您必须通过在cookie身份验证中间件上配置CookieAuthenticationProvider来控制行为,当有401未经授权的响应时:
app.UseCookieAuthentication(new CookieAuthenticationOptions { AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie, LoginPath = new PathString("/Account/Login"), Provider = new CookieAuthenticationProvider { OnApplyRedirect = ctx => { if (!IsAjaxRequest(ctx.Request)) { ctx.Response.Redirect(ctx.RedirectUri); } } } });
请注意,它会处理OnApplyRedirect事件。当调用不是Ajax调用时,我们重定向。否则,我们什么也不做,只允许将401返回给调用者。
只需从katana项目中的helper复制IsAjaxRequest检查:
private static bool IsAjaxRequest(IOwinRequest request) { IReadableStringCollection query = request.Query; if ((query != null) && (query["X-Requested-With"] == "XMLHttpRequest")) { return true; } IHeaderDictionary headers = request.Headers; return ((headers != null) && (headers["X-Requested-With"] == "XMLHttpRequest")); }