处理服务器端HTTP 4nn / 5nn错误在jQuery的ajax请求中返回整个HTML文档

要点:如何在jQuery的ajax请求中处理服务器端HTTP 4nn / 5nn错误? 这种情况涉及服务器端的JSP / Servlet Web应用程序。 在这里,我不是在讨论琐碎的运行时exception,例如NullPointerException等。 假设他们都处理完美。 这种HTTP 4nn / 5nn错误的一个很好的例子是401未授权(用户权限不足)和500内部服务器错误(数据库关闭,I / O错误, Error等)。 假设他们不能(或不应该)在编码级别被捕获。

现在我刚刚在web.xml为这些声明了一个 。 它基本上将请求转发到预定义的JSP / HTML错误页面,其中最终用户被告知发生了严重错误,并且用户可以联系xx@xx.xx以获得进一步的帮助。 同一页面还显示有关错误/exception的全局详细信息。

它在常规HTTP请求中完美运行,但是如何使用jQuery在XMLHtttp请求中处理它? 什么是最好的用户体验? 对我来说,它只是显示整个错误页面,就好像它是一个普通的HTTP请求。 我解决了它如下:

 function init() { $.ajaxSetup({ error: handleXhrError }); } function handleXhrError(xhr) { document.open(); document.write(xhr.responseText); document.close(); } 

虽然它完美无缺,但我觉得它像黑客一样。 用HTTP错误页面的内容替换整个文档。 但这也是你会遵循的方式吗? 如果没有,你可以详细说明为什么不以及你更喜欢什么方式? 我看到的唯一选择是使用JS显示一些警告/消息框以通知用户有关不可解析的错误,但是用户可以将其解除并继续使用该页面,而这是不可能的。

毕竟,以与同步请求相同的方式处理异步请求上的错误对于用户体验是最佳的。 只有

 function handleXhrError(xhr) { document.open(); document.write(xhr.responseText); document.close(); } 

当您需要加载和初始化的元素时,IE6 / 7/8中将失败。 IE6 / 7/8即不会这样做。 为了让IE做到这一点,你基本上需要保留当前的元素,并且只用$("head").html(newHead)替换它的子元素$("head").html(newHead) 。 对于元素也应该这样做。

 function handleXhrError(xhr) { var newDocument = xhr.responseText; $("head").html(newDocument.substring(newDocument.indexOf("") + 6, newDocument.indexOf(""))); $("body").html(newDocument.substring(newDocument.indexOf("") + 6, newDocument.indexOf(""))); } 

令人讨厌,但是当响应文本表示带有头部和正文的整个HTML文档时,不可能执行$(xhr.responseText) 。 当你在错误页面模板的上有一些属性时(例如ID,类等),不要忘记相应地改变子串索引。

使用JQuery对话框,如下所示:

 function handleXhrError(xhr) { ele = $("
").appendTo("body"); ele.html(xhr.responseText); $(ele).dialog();

}

我应该回答你问的其余部分。 我尽可能地抛出并捕获特定的exception,并向客户端发送特殊消息。 有时我会指示客户端运行一个可以重定向浏览器或部分刷新页面部分的function。 这取决于具体情况。 捕获400/500将处理实际错误,但您还想编写一次JS代码来过滤您将从服务器返回的自定义错误标志的所有AJAX请求,请查看此页面以获取更多信息: http:// http://www.bennadel.com/blog/1392-Handling-AJAX-Errors-With-jQuery.htm

如有必要,您还应该能够重定向到您使用window.location.href = "url-to-error-page";设置的预定义错误页面之一window.location.href = "url-to-error-page";

我认为最好是给一条短信而不是完全重写你的页面。 这样它就不会干扰页面本身。 谷歌阅读器和Gmail做这样的事情。 阅读器显示消息并且不会标记您的项目,但您仍然可以阅读所有已加载的post。

在收到导致状态不可用的错误情况后,您似乎希望保留工作页/应用程序。

我将在客户端实现状态历史记录并将页面恢复到最后一个可用状态,通过一个突出的页内元素通知用户发生了什么。

这背后的理论与交易有关。 通常,执行流程为:

  1. 指示事务管理器启动事务
    1. 开始交易
    2. 捕获状态
    3. 将控制权返回给调用代码
  2. 开始作为交易一部分的操作
  3. 出错:指示事务管理器回滚事务
    1. 将执行环境返回到上面捕获的状态
    2. 丢弃不再需要的任何数据(例如状态序列化)
  4. 成功时:指示事务管理器提交事务
    1. 根据需要完成事务中的操作
    2. 丢弃不再需要的任何数据

我还没有认真研究javascript中的事务管理。 由于您声明服务器端错误导致客户端无法使用,因此可能有一些方法可以在服务器端实现部分事务。 重要的是你不要把一半的事情留在那里,而不是在客户端。

在客户端应用程序尝试执行实际工作之前,您是否考虑过执行“预飞行检查”请求以尝试捕获这些问题?