httpError:Http 传输返回 0 状态代码

2024-01-21

我有一个登录页面:

<h:form id="f_login" >
    <f:passThroughAttribute name="data-ajax" value="false" />

    <h:messages id="message" showDetail="false" errorClass="error_msg" fatalClass="success_msg" infoClass="info_msg" warnClass="warning_msg" />

    <h:inputText value="#{loginWEB.user.email}" >
        <f:passThroughAttribute name="placeholder" value="Email" />
        <f:ajax event="change" execute="@this" />
    </h:inputText>

    <h:inputSecret value="#{loginWEB.user.senha}" autocomplete="off" >
        <f:passThroughAttribute name="placeholder" value="Senha" />
        <f:ajax event="change" execute="@this" />
    </h:inputSecret>

    <h:commandButton id="btn_login" value="Login" action="#{loginWEB.login()}" >
        <f:passThroughAttribute name="data-theme" value="g" />
        <f:ajax render="message" />
    </h:commandButton>
</h:form>

使用此操作方法:

public void login() {
    try {

        FacesContext context = FacesContext.getCurrentInstance();

        if (...) { //Verify email and password
            context.getExternalContext().redirect("/templates/main.xhtml"); 
        }
        else {
            FacesMessage message = new FacesMessage("Invalid email or password");
            message.setSeverity(FacesMessage.SEVERITY_ERROR);
            context.addMessage(null, message);
        }

    } catch (Exception e) {
        Logger.getLogger(LoginWEB.class.getName()).log(Level.SEVERE, null, e);
    }
}

提交此表单有时会导致 JS 错误:

httpError:Http 传输返回 0 状态代码。这通常是混合 ajax 和完整请求的结果。出于性能和数据完整性的原因,这通常是不希望的。

我不明白我做错了什么。这是如何引起的以及如何解决?


如果其中一个输入字段在更改时仍然具有焦点,并且通过鼠标或 [enter] 键按下提交按钮而不是按 Tab 键切换(以便首先触发输入字段的更改事件),则确实有可能出现该特定错误。 2 个 ajax 请求之间将出现竞争条件:一个由输入字段的更改事件触发,另一个由提交按钮的操作事件触发。在这种情况下,无法确定哪一个会先到达服务器。

在 JSF 中,ajax 请求是queued https://stackoverflow.com/questions/13746618/are-jsf-primefaces-ajax-requests-really-asynchronous。因此,如果其中一个访问服务器,另一个将等待它返回并完成。当提交按钮的 ajax 请求是第一个到达服务器的请求时,就会出现您的问题。如果登录成功,服务器将返回执行重定向的指令。此重定向由 JavaScript 在 ajax 请求完成期间处理。此后,队列中的下一个 ajax 请求(如果有)将被触发(尽管存在重定向!在我看来,这又是 JSF ajax 引擎中的一个设计错误,但除此之外)。但是,由于文档已通过重定向更改,因此第二个 ajax 请求未命中,从而导致此错误。

总而言之,这种ajax形式的做法有些奇怪。输入字段和提交按钮均通过 ajax 单独发送其值,而不是通过提交按钮一次性发送所有值。看起来很像你最初拥有的<f:ajax>在提交按钮中,但您认为输入值未得到处理,因此您决定添加另一个<f:ajax>到那些输入字段。

这并不完全是正确的做法。你应该使用execute="@form"在提交按钮中,以指示它执行(处理)整个表单。

因此,所以:

<h:form id="f_login">
    <f:passThroughAttribute name="data-ajax" value="false" />

    <h:messages id="message" showDetail="false" errorClass="error_msg" fatalClass="success_msg" infoClass="info_msg" warnClass="warning_msg" />

    <h:inputText value="#{loginWEB.user.email}">
        <f:passThroughAttribute name="placeholder" value="Email" />
    </h:inputText>

    <h:inputSecret value="#{loginWEB.user.senha}" autocomplete="off">
        <f:passThroughAttribute name="placeholder" value="Senha" />
    </h:inputSecret>

    <h:commandButton id="btn_login" value="Login" action="#{loginWEB.login}">
        <f:passThroughAttribute name="data-theme" value="g" />
        <f:ajax execute="@form" render="message" />
    </h:commandButton>
</h:form>

这样,一次只会触发一个 ajax 请求,从而消除了竞争条件的风险。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

httpError:Http 传输返回 0 状态代码 的相关文章

随机推荐