答案在问题中 - '重复表单提交',您有两个请求被发送到服务器,因此您必须同时处理它们。
因此,浏览器向服务器发送了两个相同的请求,因此该操作将被调用两次。
第一个请求将成功,并使用 '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 中,而无需对其进行自定义。