Django:多次提交相同的表单导致 403 CSRF 异常
Django: Submitting same form multiple times causes 403 CSRF exception
我有一个创建旅行的表格。此表单通过 AJAX
提交,创建行程,然后清除 form
输入,以便用户无需刷新页面即可创建另一个项目。
问题是第一次提交后,Django
returns:
CSRF verification failed. Request aborted.
我知道问题是 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')
但我不知道该怎么做。你有什么想法吗?
不应针对每个请求更改 CSRF 令牌。它应该存储在 cookie 中并且仅在用户每次登录时更改,因此除非您的应用设置为每次都从头开始重新验证用户,否则不应该发生这种情况。
也许您只是没有在后续请求中发送它?我的盲目猜测是,当您清除页面上的表单时,您会以某种方式清除令牌。记录您的所有请求和响应,看看是否遗漏了。
如果它实际上正在改变,你不知道为什么,或者如果有理由需要保持这种状态,那么我会尝试让服务器对 AJAX 调用的响应包括新令牌。
我有一个创建旅行的表格。此表单通过 AJAX
提交,创建行程,然后清除 form
输入,以便用户无需刷新页面即可创建另一个项目。
问题是第一次提交后,Django
returns:
CSRF verification failed. Request aborted.
我知道问题是 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')
但我不知道该怎么做。你有什么想法吗?
不应针对每个请求更改 CSRF 令牌。它应该存储在 cookie 中并且仅在用户每次登录时更改,因此除非您的应用设置为每次都从头开始重新验证用户,否则不应该发生这种情况。
也许您只是没有在后续请求中发送它?我的盲目猜测是,当您清除页面上的表单时,您会以某种方式清除令牌。记录您的所有请求和响应,看看是否遗漏了。
如果它实际上正在改变,你不知道为什么,或者如果有理由需要保持这种状态,那么我会尝试让服务器对 AJAX 调用的响应包括新令牌。