Django:多次提交相同的表单会导致403 CSRF异常

时间:2018-01-06 14:34:33

标签: jquery ajax django forms csrf

我有一个创建旅行的表格。此表单通过AJAX提交,已创建行程,然后清除form输入,以便用户无需刷新页面即可创建其他项目。

问题是,首次提交后,Django会返回:

  

CSRF验证失败。请求中止。

我知道问题是CSRF Token已经被修改但是由于页面没有刷新,因此没有反映在用户cookie中。我想到的唯一方法是使用csrfexempt

查看

class TripCreationView(LoginRequiredMixin, SuccessMessageMixin, CreateView):
    form_class = TripCreationForm
    template_name = 'trips/add_new_trip.html'
    success_message = _('New trip has been added')
    context_object_name = 'trip_creation_form'

    def post(self, request, *args, **kwargs):
        return super(TripCreationView, self).post(self, request, *args, **kwargs)

    def get_form_kwargs(self):
        kwargs = super(TripCreationView, self).get_form_kwargs()
        kwargs['user'] = self.request.user
        return kwargs

    def get_context_data(self, **kwargs):
        context = super(TripCreationView, self).get_context_data(**kwargs)
        context['trip_creation_form'] = context['form']
        return context

    def get_initial(self):
        initial = super(TripCreationView, self).get_initial()
        initial.update({k: v for k, v in self.request.GET.iteritems()})
        return initial

    def form_valid(self, form):
        if self.request.is_ajax():
            form.save()
            return JsonResponse({'status':'OK'})

    def get_success_url(self):
        return self.request.POST.get('success_url') or reverse('frontend:homepage')

但我不知道如何使这项工作。你有什么想法吗?

1 个答案:

答案 0 :(得分:1)

CSRF令牌不应该针对每个请求进行更改。它应该存储在cookie中,并且每次用户登录时都会更改,因此除非您的应用程序设置为每次都从头开始重新验证用户,否则不会发生这种情况。< / p>

也许您只是不在后续请求中发送它?我的盲目猜测是,当您清除页面上的表单时,您会以某种方式清除令牌。记录您的所有请求和回复,看看它是否丢失。

如果它实际上在改变你就无法弄清楚原因,或者是否有理由需要保持这种状态,那么我会尝试让服务器对AJAX调用的响应包括新令牌。