问题
I got some good advice on StackOverflow about how to remove all hidden fields using JavaScript.
Submitting the form sends the user to /submit
, calling the submit_form
view. In my views.py file, I define my index page (with the form), and the page that receives the submission (my /index
page prints errors for me, but that shouldn't influence anything):
def index(request, error_message = ''):
t = get_template('index.html')
html = t.render(Context( { 'ERROR_MESSAGE': error_message } ))
return HttpResponse(html)
def submit_form(request):
# get the POST data out of request and do something
pass
I've been able to suppress the error by changing the code to:
from django.contrib.csrf.middleware import csrf_exempt
@csrf_exempt
def submit_form(request):
# get the POST data out of request and do something
pass
This essentially turns off CSRF for the submit_form function. However, I'm sure this is not the ideal fix (now I'm not checking for forgeries in my form).
I tried more sophisticated fixes, like
- Adding this code to immediately follow the jQuery code (which removes hidden fields from submission)
init:function(){
var ac=this
# advice from StackOverflow to remove hidden
# fields from POST submission
jQuery(document).ready(function($){
$("form").submit(function() {
$(this).find(":hidden").remove();
});
# AJAX CSRF code inserted here
#...
}
- Adding `{% csrf_token %}` immediately after my form declaration. I also tried adding code to my `index` view to send the `csrf_token` to `index`; that made the token viewable in the rendered index.html source (which I gathered was a bad idea).
I've seen several questions asking about things like this (and references in the Django book), but haven't seen a simple and clear answer. For instance-- even if I was going to tolerate publishing my csrf_token
(which, still I know is a bad idea), it is still unclear whether I should render that in my index page (and then it will submitted form will have the token) or whether I am supposed to do something in my submit_form
code. The Django code book (linked above) uses my_view
as the view function where the token is rendered; this name is not very helpful!
Does anyone have a small example with CSRF working (with javascript modifying the form)? I really think it would be useful (to me and to lots of other people on StackOverflow to see this. Ideally, it would be as simple as possible (two views: one delivers the form, the other prints its contents).
Thanks a lot for your help.
Update: I still get this error, even when I prefent the csrfmiddlewaretoken from being removed. When I *do not do any JavaScript processing, my form is fine. And I've verified that only my
Is there some way that CSRF can see that some form elements are removed? I can't find anything different in my QueryDict
object (that sends the data from the form using POST).
I'd really appreciate any help!
回答1:
The problem is that you remove the hidden CSRF-field and the solution is to not remove this field, you could probably do that with the jQuery selector to have it ignore that field with :not(input[name=csrfmiddlewaretoken]).
Btw, Django doesn't have a problem with unknown field names sent to the form-class, it will happily ignore them so the removal of the hidden fields tradeoff is very small.
来源:https://stackoverflow.com/questions/7747209/csrf-error-in-django-after-removal-of-hidden-fields