我在寻找一种通用的方法,以防止多个表单提交。 我发现这个方法看起来很有希望。 虽然我不想包含这个片段在我所有的意见。 它可能更容易与请求处理器或中间件来做到这一点。
任何最佳实践的建议?
我在寻找一种通用的方法,以防止多个表单提交。 我发现这个方法看起来很有希望。 虽然我不想包含这个片段在我所有的意见。 它可能更容易与请求处理器或中间件来做到这一点。
任何最佳实践的建议?
客户端,开始使用JavaScript。 你永远不能信任的客户端,但它的一个开端。
即
onclick="this.disabled=true,this.form.submit();
服务器端你“可以”插入一些内容即校验数据库。 如果它是一个记录你插入到数据库中使用model.objects.get_or_create()
来强制你应该使用unique_together数据库级别的唯一性。
最后 :HTTPRedirect是最好的,我在用,当用户处理付款是刚刚发出HTTPRedirect()将感谢你/构造页面的方法。 这样,刷新表单不会再次提交,如果他们回去,并尝试重新提交表单(而不刷新形式)Django的跨站请求伪造(CSRF)会失败,完美!
我也试图寻找避免重复记录产生一个很好的方式,当用户在一个提交按钮DBL点击。 这不是关于PRG问题是容易被重定向固定。
所以,在此基础关心的问候,在服务器端与HTTPRedirect解决没有帮助。
在客户端,我发现了两个问题,当我禁用按钮之前提交:
form.submit()
将被浏览器,如果表单是无效=>提交按钮仍所中断disabled=true
。 disabled=true
。 因此,这里是我的第一个客户端的问题(HTML5验证)的解决方法:
isFormHtml5Valid(form) {
for(var el of form.querySelectorAll('input,textarea,select')){
if(!el.checkValidity())
return false;
}
return true;
}
mySubmitButton.onclick = function() {
if(this.form && isFormHtml5Valid(this.form))
this.disabled=true;
this.form.submit();
}
我试图找到一个客户端的解决方法为第二客户端的问题(浏览器缓存中的DOM),但毫无效果(onbeforeunload,...)。 所以,我目前使用的“浏览器缓存”问题的解决方法是增加对有关意见顶部的@never_cache装修(从服务器端,指示客户端不缓存)。 请让我知道,如果你有更好的解决方法。
最后但并非最不重要的, 我会很感激固定在服务器端这个问题 。 由于该CSRF溶液似乎不适合由会话生成CSRF令牌 (未每种形式)。 因此,这里是我的工作和我的问题的状态:
让我知道,如果你有专门的好办法。
编辑1:可能是答案的一小部分: 同步(或似曾相识)令牌
但我没有找到在Django的任何implemantation。
使用HttpResponseRedirect
创建一个新的视图(可以说thank_you
)成功的消息表单提交后显示,并返回一个模板。
成功的表单提交后返回做HttpResponseRedirect(“/感谢你/”)到新感谢您查看
from django.http import HttpResponseRedirect
def thank_you(request, template_name='thank-you.html'):
return render_to_response(template_name,locals(),context_instance=RequestContext(request))
在urls.py
url(r'^thank-you/$','thank_you', name="thank_you")
多形式提交是因为当页面刷新相同的URL访问,这调用同样的观点连连,因此多个条目保存在数据库中。 为了防止这种情况,我们需要重定向到新的URL /视图中的反应,所以下一次页面刷新,这将创下新的URL /视图。
至于#2,这是最好做的是,在onsubmit
处理程序,而不是onclick
提交按钮。 如多个提交按钮这将处理案件或是否有任何HTML5客户端表单验证。 在jQuery中它会看起来像:
$('#edit_form').submit( function(event) {
// disable to avoid double submission
$('#submit_button').attr('disabled', true);
});
然而,有一个问题,这并不考虑是,如果用户取消部分提交方式。 例如,如果你点击“提交”,然后立即按下“Esc”键,浏览器将停止提交,但“提交”按钮,将已被禁用。
此外,它可能有一个由打“进入”提交,该解决方案将无法阻止这种形式从两次提交表单。