什么原因导致此页面上的完整请求?

时间:2011-08-11 13:26:42

标签: ajax jsf-2 glassfish-3

考虑以下jsf页面:

<h:body>
    <h:form id="SessionStartDialog">
        <table>
            <tr>
                <td class="label">
                    <h:outputLabel
                        value="Enter your username:" 
                        for="UsernameField"/>
                </td>
                <td class="input">
                    <h:inputText 
                        id="UsernameField"
                        value="#{login.username}"
                        validator="#{login.validateUsername}"
                        tabindex="1">
                        <f:ajax render="SelectWorkingSetListbox
                                StartSessionButton UsernameMessage" />
                    </h:inputText>
                    <h:message 
                        id="UsernameMessage"
                        for="UsernameField" />
                </td>
            </tr>
            <tr>
                <td class="label">
                    <h:outputLabel
                        value="Choose a working-set:" 
                        for="SelectWorkingSetListbox"/>
                </td>
                <td class="input">
                    <h:selectOneMenu
                        id="SelectWorkingSetListbox"
                        tabindex="2"
                        disabled="#{!login.showWorkingSets}"
                        value="#{login.selectedWorkingSetName}">
                        <f:selectItems 
                            value="#{login.workingSetNames}"/>
                        <f:ajax />
                    </h:selectOneMenu>
                </td>
            </tr>
        </table>
        <h:commandButton 
            id="StartSessionButton"
            styleClass="StartSessionButton"
            disabled="#{!login.showWorkingSets}"
            value="Start Session" 
            tabindex="3"
            action="#{login.startSession}" >
            <f:ajax execute="@form"/>
        </h:commandButton>
    </h:form>
</h:body>

其中的某些内容导致Safari报告ajax和完整请求混合的错误。我不明白为什么,因为所有导致请求的组件都包含<f:ajax> - 标签。这有什么问题?

更新

我创建了一个触发此错误的最小示例:

<h:body>
    <h:form>
        <f:ajax render="TextField">
            <h:inputText value="#{theBean.text}" />                
        </f:ajax>
        <h:outputText id="TextField" value="#{theBean.text}" />
    </h:form>
</h:body>

theBean是一个简单的视图范围bean,textString类型的属性。由于某种原因,这会在Safari 5.1中触发以下消息:

  

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

更新2 这样做的原因似乎是在enter字段内点击input始终会触发完整表单提交。我不知道如何防止这种情况。如第一个示例所示,我希望用户输入用户名,然后启用表单的其他组件(仅当用户名已知时)。我该如何正确实现?

2 个答案:

答案 0 :(得分:1)

问题的原因在于,在没有<h:commandButton>的情况下(在第一个示例中它最初被禁用,在第二个示例中,没有),按回车将触发整个提交表格,导致问题中显示的错误。

现在的解决方案是始终启用<h:commandButton>。由于启用了<f:ajax>,因此会阻止完整提交。

P.S。:我发布了这个答案,为其他人展示了一个可能的解决方案。我仍然想知道是否有更好的解决方案(不需要<h:commandButton>存在的解决方案。)

答案 1 :(得分:1)

我会抓取<form>上的 Enter 键,而是触发按下此键的onchange元素上的<input>

<h:form onkeydown="enterToChange(event)">
    ...
</h:form>

function enterToChange(event) {
  if (event.keyCode == 13 && event.target.tagName != 'textarea') {
    event.stopPropagation(); // Don't bubble up.
    event.preventDefault();  // Prevent default behaviour (submitting the form).
    event.target.onchange(); // Trigger onchange where key was actually pressed.
  }
}

请注意,这会忽略textareas上的回车键,您当然希望保留预期的行为(插入新行)。

如果有必要,您可以添加额外的检查以查看提交按钮是否不是disabled,如果是这种情况,那么只需让活动开始。