【问题标题】:FullAjaxExceptionHandler does not redirect to error page for Ajax requestFullAjaxExceptionHandler 不会重定向到 Ajax 请求的错误页面
【发布时间】:2013-09-06 23:13:30
【问题描述】:

我知道这里有很多关于这个问题的问题,但几乎所有问题都建议添加以下代码,因为 FullAjaxExceptionHandler “上方”还有另一层发送普通重定向而不是执行 Ajax 重定向(请参阅@ 987654321@):

if ("partial/ajax".equals(request.getHeader("Faces-Request"))) {
// JSF ajax request. Return special XML response which instructs JavaScript that it should in turn perform a redirect.
response.setContentType("text/xml");
response.getWriter()
    .append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>")
    .printf("<partial-response><redirect url=\"%s\"></redirect></partial-response>", loginURL);
} else {
    // Normal request. Perform redirect as usual.
    response.sendRedirect(loginURL);
}

我的问题是我只是配置 Omnifaces 的 FullAjaxExceptionHandler 来完成所有错误处理,我没有 Spring Security 或容器管理的安全性在 FullAjaxExceptionHandler 可以做之前拦截请求。我可以断点到 FullAjaxExceptionHandler 并看到当执行以下代码行时,我的错误页面仍然没有被重定向。

String viewId = Faces.normalizeViewId(errorPageLocation);
ViewHandler viewHandler = context.getApplication().getViewHandler();
UIViewRoot viewRoot = viewHandler.createView(context, viewId);
context.setViewRoot(viewRoot);
context.getPartialViewContext().setRenderAll(true);
        ...
    context.renderResponse();

相反,引发异常的 Ajax 请求在其响应正文中包含以下内容:

<?xml version='1.0' encoding='UTF-8'?>
    <partial-response>
        <changes>
            <update id="javax.faces.ViewRoot"><![CDATA[<html xmlns="http://www.w3.org/1999/xhtml">... html of error page here ... </html>]]></update>
            <update id="javax.faces.ViewState"><![CDATA[-3527653129719750158:5595502883804776498]]></update>
        </changes>
    </partial-response>

看起来 FullAjaxExceptionHandler 没有做它应该做的事情,或者我错过了什么?

更新

附加浏览器JS输出控制台屏幕截图。

已识别问题

原来我的错误页面的HTML格式错误,包含如下sn-p,导致浏览器出现标签不匹配错误:

<script type="text/javascript">
//<![CDATA[
scrollTo(0, 0);
//]]>
</script>

这似乎过早地关闭了 CDATA 标记。这个 HTML 是 &lt;h:outputScript/&gt; 标记的结果,我删除了它,因为我真的不需要它。

【问题讨论】:

  • 哪个 PrimeFaces 版本?旧版本在使用@all 时遇到问题:code.google.com/p/omnifaces/wiki/KnownIssues#PrimeFaces_2.0-3.1 至少要排除 PrimeFaces(及其捆绑的 jQuery)成为原因,如果您使用 &lt;h:commandButton&gt;&lt;f:ajax&gt; 而不是 &lt;p:commandButton&gt; 会怎样?顺便说一句,Ajax 响应看起来完全没问题。所以在这一步之前一切都很好。由于某种原因,它只是没有被 JavaScript 应用于当前的 HTML 文档,所以问题本质上是在 JS 方面。如果 JS 上下文有一些错误/冲突,也可能发生这种情况。你检查过 JS 控制台吗?
  • 我正在使用 PF3.5。我在控制台中看到的唯一错误是它无法解析部分更新。我将使用控制台屏幕截图更新我的帖子。我从使用 PF 按钮更改为 ,确实,我按预期重定向到错误页面。我不确定这是否是我可以解决的问题,是吗?
  • 好的,这是一个 PF 问题。在发布答案之前,我想知道您使用的是哪个浏览器,以及您是否有 &lt;h:body&gt;&lt;h:body someAttribute="someValue"&gt;
  • 哦,它已修复!我的错误页面的 HTML 格式不正确,因此错误的结束标记是有效错误。结束标记来自我的 errorPage.xhtml 中的这一行: scrollTo(0, 0);
  • 我不需要它,所以我删除了它,它现在可以工作了!请发布答案,感谢您为我指明正确的方向!

标签: ajax jsf-2 primefaces error-handling omnifaces


【解决方案1】:

在最初的问题之后多年,现在使用 Wildfly 15、JSF 2.3、OmniFaces 3.2,我偶然发现了一个类似的问题:在 ajax 调用期间出现异常时 FullAjaxExceptionHandler 的部分响应格式错误。原因是响应中嵌套了 CDATA,因此注释掉了响应的一部分,导致 XML 解析错误。罪魁祸首似乎是 JSF 标记 ui:debug。我已删除该声明,现在它按预期工作。

【讨论】:

    【解决方案2】:

    ajax 响应看起来完全没问题,它有一个包含整个错误页面文档的 &lt;update id="javax.faces.ViewRoot"&gt;,所以 FullAjaxExceptionHandler 正常工作。

    在检索到 ajax 响应之后,您的具体问题更有可能是在客户端甚至错误页面文档本身引起的。然后轮到 JavaScript 解析该 ajax 响应并相应地替换当前的 HTML 文档。检查浏览器的 JavaScript 控制台应该可以提供有关该步骤中问题的任何线索。在您的特定情况下,该问题似乎是由 &lt;h:outputScript&gt; 呈现的内容周围的嵌套 CDATA 块引起的,这反过来又导致 JavaScript 解析错误。

    不幸的是,我手头上的任何 Mojarra 版本都无法重现该问题。也许您在某个地方有一个自定义/第 3 方脚本渲染器,负责添加 CDATA 块。当PartialViewContext#isAjaxRequest() 返回true 时,该脚本渲染器应该跳过CDATA 块。如果您仍然无法弄清楚,那么最好的办法是用纯 HTML &lt;script&gt; 替换 &lt;h:outputScript&gt;,甚至完全删除它——就像您最终所做的那样。

    【讨论】:

    • 您是否使用 Mojarra 2.1.24 对其进行了测试?无论如何,看起来我可能仍然需要我的错误页面上的 javascript,感谢您的解决方法。
    猜你喜欢
    • 2013-04-08
    • 2013-08-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多