1

我正在尝试在我的 Grails 应用程序中处理重复的表单提交。所以我useToken="true"在我的表单中设置,这就是我尝试withForm在我的控制器中使用该方法的方式:

def myControllerAction {
    withForm {
       *my action's logic*
    }
}

但是,我最终得到:Error 310 (net::ERR_TOO_MANY_REDIRECTS): There were too many redirects.在我的浏览器中。所以我想我没有正确使用它,我还没有在网上找到任何关于如何正确使用该方法的示例。

对此的任何帮助都会非常有帮助。提前谢谢你。

4

2 回答 2

2

您的示例中并没有太多内容:简短的回答是,如果令牌无效,您必须做一些事情来导致重定向。

Grails 手册展示了如何使用它。

所有的逻辑都是在其中放置一个具有唯一值的隐藏字段。该值存储在会话中,因此您的会话必须正常工作(如果托管在集群环境中,您需要会话亲和性或共享会话)。提交表单时,它会查找该唯一值,并确定它是否已经提交。

您似乎没有处理invalidToken任何地方,因此您可能正在处理令牌未正确存储或传递的情况,并且您的逻辑导致重定向。如果您使用 aget而不是 a进行重定向post,这可能会导致重定向循环。(即使第一次正确处理了令牌,这也可能导致重定向循环。)

我会查看您的代码并找出重定向的来源。它不是由令牌直接引起的。

于 2012-05-04T03:06:40.780 回答
1

答案在问题中 - '重复表单提交',您有两个请求被发送到服务器,因此您必须同时处理它们

因此,浏览器向服务器发送了两个相同的请求,因此该操作将被调用两次。

第一个请求将成功,并使用 'withForm' 块中的代码,并且令牌将递增。

第二个请求仍然包含与第一个请求相同的令牌,但服务器已丢弃该令牌,因此第二个请求使用“invalidToken”块中的代码,或者如果您省略了“invalidToken”块,则使用默认块.

重要的一点是 - 这是第二个(错误)请求将决定浏览器上显示的内容,因为它在第一个之后到达,所以我决定在处理错误请求时将用户重定向回索引,他们应该能够看到由第一个请求创建和保存的记录。IE

     }.invalidToken 
 {
    println "myController: swallowing request with invalidToken (probably a double-click or due to using back button in browser.)"
    flash.invalidToken = " " // just enough to trigger the g:if in the index.gsp
    redirect action:"index", method:"GET"
 }

然后在 index.gsp 中,我显示一条消息:

<g:if test="${flash.invalidToken}">
<ul class="errors" role="alert">
<li>
    <g:message code="error.doubleclick" 
           default="oops, the item you are creating exists already (maybe you double-clicked on the 'Save' button ?).  Click on the item in the list below to continue working with that item."
/>
</li>
</ul>

这可以正常工作,并且足够通用,您可以将 n 粘贴到任何控制器和 index.gsp 中,而无需对其进行自定义。

于 2014-06-07T15:10:25.787 回答