是什么导致此页面上出现完整请求?

发布于 2024-11-29 05:37:37 字数 3074 浏览 1 评论 0原文

考虑以下 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 和完整请求混合的错误。我不明白为什么,因为引起请求的所有组件都包含 -标签。这里有什么问题呢?

更新

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

<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,text字符串。由于某种原因,这会在 Safari 5.1 中触发以下消息:

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

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

Consider the following jsf page:

<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>

Something in there causes Safari to report an error that ajax and full requests are being mixed. I do not understand why, as all components that cause requests contain <f:ajax>-tags. What is the problem here?

Update:

I have created a minimal example that triggers this error:

<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 is a simple view-scoped bean and text a property of type String. For some reason this triggers the following message in Safari 5.1:

httpError: The Http Transport returned a 0 status code. This is
usually the result of mixing ajax and full requests. This is usually
undesired, for both performance and data integrity reasons.

Update 2 The reason for this seem to be that hitting enter inside the input-field always triggers a full form submit. I have no idea how to prevent this. As shown in the first example, I want to user to enter a username, and then the other components of the form get enabled (only if the username is known). How would I implement this correctly?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

空城旧梦 2024-12-06 05:37:37

我会捕获

上的 Enter 键,并在 上触发 onchange > 按下此键的元素。

<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.
  }
}

注意,这会忽略文本区域上的回车键,您当然希望在其中保留预期的行为(插入新行)。

如果有必要,您可以添加额外的检查来查看提交按钮是否未禁用,如果是这样,则让事件继续。

I'd capture the Enter key on the <form> and instead trigger onchange on the <input> element where this key was pressed.

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

with

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.
  }
}

Note that this ignores the enter key on textareas where you'd of course like to keep the intended behaviour (inserting a new line).

You could if necessary add an extra check to see if the submit button is not disabled and if that is the case, then just let the event go.

难得心□动 2024-12-06 05:37:37

问题的原因是,在没有 的情况下(在第一个示例中它最初被禁用,在第二个示例中没有),按 return 将触发提交整个表单,导致问题中显示的错误。

目前的解决方案是始终启用 。由于它是 启用的,这将阻止完整提交。

PS:我发布此答案是为了向其他人展示可能的解决方案。我仍然想知道是否有更好的解决方案(不需要存在 的解决方案)。

The cause of the problem is that, in the absence of an <h:commandButton> (in the first example it is initially disabled, in the second example, there is none), pressing return will trigger a submit of the entire form, causing the error shown in the question.

The resolution for now is to have the <h:commandButton> always enabled. Since it is <f:ajax>-enabled, this will prevent a full submit.

P.S.: I posted this answer to show a possible solution for others. I would still like to know if there is a better solution (one that does not require the presence of a <h:commandButton>).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文