在构建将jquery ajax合并到其GUI中的内容管理系统时,我遇到了一个障碍。似乎有些客户花了太长时间思考他们要写什么,因此服务器会话将它们记录下来,自然就是网络他们根本不知道这一点。当他们尝试提交更改时,我使用ajax调用服务器来保存数据。
接下来我希望发生的是MVC服务器应用程序将返回“401 Unauthorized”状态。然后,我可以获取我的jquery ajax对象,要求用户登录,然后在用户获得授权后重新发送更改。
但是,从MVC应用程序实际返回的是“302 Found”状态和到我的登录表单页面的重定向URL。登录表单页面返回“200 OK”状态代码,jquery ajax对象调用成功事件,告诉用户一切都成功,因为这就是MVC应用程序所说的内容。
我有没有办法让MVC应用程序以我认为应该的方式播放或者我必须修改我的jquery ajax事件以检测登录页面?
更新
我使用了反射器来查看MVC代码和authorize属性,返回NotAuthorizedResult,其代码如下(0x191 = 401)
public override void ExecuteResult(ControllerContext context)
{
if (context == null)
{
throw new ArgumentNullException("context");
}
context.HttpContext.Response.StatusCode = 0x191;
}
我在想,表格授权HttpModule可能会看到401并强制重定向。
答案 0 :(得分:6)
void context_EndRequest(object sender, EventArgs e)
{
var app = sender as HttpApplication;
var response = app.Response;
var request = app.Request;
if ((response.StatusCode == 302) && IsAjaxRequest(request))
response.StatusCode = 401;
}
在HttpModule中,它将依次在FormsAuth模块之后,因此将更正状态代码。不是很好但很有效。
答案 1 :(得分:5)
我真的很喜欢这个解决方案。通过将ajax请求的302响应更改为401,它允许您在客户端设置ajax以监视查找401的任何ajax请求,以及是否找到重定向到登录页面的请求。非常简单有效。
的Global.asax:
protected void Application_EndRequest()
{
if (Context.Response.StatusCode == 302 &&
Context.Request.Headers["X-Requested-With"] == "XMLHttpRequest")
{
Context.Response.Clear();
Context.Response.StatusCode = 401;
}
}
客户端代码:
$(function () {
$.ajaxSetup({
statusCode: {
401: function () {
location.href = '/Logon.aspx?ReturnUrl=' + location.pathname;
}
}
});
});
答案 2 :(得分:1)
我发现更轻量级的方法只是将自定义HTTP标头添加到登录页面,然后检查AJAX成功回调中是否存在该标头。
IE中。在LoginController中(这是一个MVC项目,但同样的原则应该适用于其他ASP.NET解决方案):
public ActionResult Login(string returnUrl = "")
{
Response.AddHeader("X-Unauthorized", "true");
...
然后在客户端AJAX处理程序中:
success: function(data, textStatus, jqXhr)
{
if (jqXhr.getResponseHeader("X-Unauthorized"))
{
...
这至少对我有用。