【发布时间】:2014-06-07 02:34:51
【问题描述】:
场景如下:
我需要通过 AJAX 从服务器获取一些 JSON 数据(ASP.NET MVC 应用程序 + ServiceStack 服务)。如果用户的会话过期,那么我不会返回 JSON,而是重定向到登录页面,该页面由 jQuery 自动执行,因此 AJAX 调用的结果最终成为登录表单的原始 HTML。我需要以不同的方式处理这两种情况:
- 如果结果是 JSON,则使用它使用
.done()承诺更新 UI - 如果结果是 HTML 则弹出登录对话框。
所以我必须修改传递给done() 回调的参数。到目前为止,这是我尝试过的:
function getSomeData()
{
return $.ajax(
{
/*
...set my AJAX config options...
*/,
error: function(xhr, status, errorText)
{
// handle the error
},
success: function(data)
{
// if the AJAX call returned a login form instead of expected JSON
// result (because the user's session has expired) then show a
// login dialog and resolve the jQuery promise with 'null' instead
// of original 'data'
if (isLoginFormHTML(data))
{
showModalLoginDialog(data);
data = null; // neither this...
return null; // ... nor this seem to work!
}
}
});
}
function updateUI()
{
getSomeData().done(function(jsonData)
{
if (jsonData)
{
// do something
}
});
}
不幸的是,无论我在我的success函数中是data = null还是return null,传递给done()回调的参数都包含从服务器返回的原始data,可能是HTML会话过期时的登录表单。
所以问题是,我如何告诉 jQuery 将其他内容传递给done()?
PS 当然,我可以在 updateUI 方法中执行 isLoginFormHTML() 检查,但我试图避免这种情况,以保持数据检索和 UI 更新逻辑分开.
【问题讨论】:
-
这不能回答你的问题,但我的第一个冲动是在会话到期的情况下返回错误,而不是 HTML。然后,您可以通过拉取并显示登录表单来处理该特定错误。此外,即使出现错误,也会调用 done(),因此无论您如何处理登录 HTML,您都可能希望使用 getSomeData().success()。
-
使用
.then而不是success: -
Dave:我无法控制服务器的响应,因为重定向到登录页面是由我的 ASP.NET MVC 应用程序使用的 FormsAuthentication 自动完成的。
-
Benjamin Gruenbaum:感谢您的建议,看起来很有希望。找到解决方案后,我会更新我的帖子。
-
@CaspianCanuck 这就是解决方案,
success:不是承诺的延续。返回$.ajax(..).then(function(){ ...,如果你想发出错误信号,我建议你改为 throw 来导致 promise 被拒绝(就像同步的 throw)。
标签: javascript jquery ajax promise