FullAjaxExceptionHandler不会重定向到Ajax请求的错误页面 [英] FullAjaxExceptionHandler does not redirect to error page for Ajax request

查看:205
本文介绍了FullAjaxExceptionHandler不会重定向到Ajax请求的错误页面的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道这里有很多问题,但是几乎所有的人都建议添加以下代码,因为在FullAjaxExceptionHandler上方的另一层正在发送普通重定向而不是执行Ajax重定向(请参见类似的问题):

I know there has been numerous questions here on this question, but almost all of them suggest adding the following code because there is another layer "above" the FullAjaxExceptionHandler that is sending a plain redirect instead of doing an Ajax redirect (see this similar question):

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并看到执行以下代码行时,我的错误页面仍然没有被重定向.

My question is that I'm simply configuring Omnifaces's FullAjaxExceptionHandler to do all the error handling, I do not have Spring Security or container managed security that is intercepting the request before FullAjaxExceptionHandler can do it's thing. I can breakpoint into FullAjaxExceptionHandler and see that when the following lines of code is executed, my error page is still not being redirected.

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请求的响应主体中包含以下内容:

Instead, the Ajax request where the exception originated has this in it's response body:

<?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似乎没有执行应做的工作,或者我错过了什么?

It looks like FullAjaxExceptionHandler isn't doing what it's supposed to do, or am I missing something?

更新

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

Attaching browser JS output console screen cap.

已确定问题

结果是我的错误页面的HTML格式错误,其中包含以下代码段,这导致浏览器中的代码错误匹配:

Turns out that the HTML of my error page is malformed, it contains the following snippet, which results in the mismatched tag error in the browser:

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

这似乎已经过早关闭了CDATA标签.该HTML是<h:outputScript/>标记的结果,由于我确实不需要它,因此将其删除.

This seemed to have closed the CDATA tag prematurely. This HTML was a result of the <h:outputScript/> tag, which I removed since I don't really need it.

推荐答案

ajax响应看起来完全正常,它的<update id="javax.faces.ViewRoot">包含整个错误页面文档,因此FullAjaxExceptionHandler可以正常工作.

The ajax response looks completely fine, it's having an <update id="javax.faces.ViewRoot"> containing the whole error page document, so the FullAjaxExceptionHandler did its job properly.

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

Your concrete problem is more likely caused in the client side or even in the error page document itself, after the ajax response has been retrieved. It's then JavaScript's turn to parse that ajax response and replace the current HTML document accordingly. Checking the browser's JavaScript console should give any clues as to problems during that step. In your particular case, the problem seems to be caused by a nested CDATA block around the content rendered by <h:outputScript> which in turn caused a JavaScript parsing error.

不幸的是,我手头的任何Mojarra版本都无法重现该问题.也许您在某个自定义/第三方脚本渲染器的某个位置,负责添加该CDATA块.当PartialViewContext#isAjaxRequest()返回true时,该脚本渲染器应跳过CDATA块.如果仍然无法解决问题,那么最好的选择是将<h:outputScript>替换为纯HTML <script>,甚至将其完全删除—就像您最终所做的那样.

Unfortunately, I can't reproduce the problem with any Mojarra version I've at hands. Perhaps you've somewhere a custom/3rd party script renderer who's responsible for adding that CDATA block. That script renderer should skip the CDATA block when PartialViewContext#isAjaxRequest() returns true. If you still can't figure it out, then your best bet is to replace the <h:outputScript> by a plain HTML <script> or even to remove it altogether — as you ultimately did.

这篇关于FullAjaxExceptionHandler不会重定向到Ajax请求的错误页面的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆