0
votes

I've been looking for few days now how to convert form submissions to ajax with jquery, and the csrf token issue is puzzling me.

I solved the problem by adding the javascript snippet found here : https://docs.djangoproject.com/en/dev/ref/contrib/csrf/#ajax

But when stumbling on stackoverflow, I found simpler answers (not the first one): Django CSRF check failing with an Ajax POST request

Some answers suggest to simply add the following to the post data: csrfmiddlewaretoken: '{{ csrf_token }}'

But this seems too good to be true, if that was that easy, why would we need to copy the long snippet from the django website ? Also there's a quick comment to one of the replies about static JS. I don't really get it.

Could anyone please explain why the simplest solution isn't the best, and give some practical examples ?

Thanks

1

1 Answers

1
votes

The two solutions are effectively doing exactly the same thing. Supplying the csrftoken to Django in the request. They're just doing it in different ways.

'Simpler' option

For a single jQuery call in a Django template, it may be simpler to use the {{ csrf_token }} tag to add to the post data. However as soon as there are multiple calls in multiple places, it becomes harder to maintain.

jQuery Code

On the other hand, the jQuery code:

  • Can be included in one place, in a static .js file
  • Doesn't need to be in a django template
  • Can be included in multiple pages
  • Works for all jQuery Ajax calls without modifying the individual calls
  • Includes working with any third party jQuery libraries
  • Is the same everywhere, so easy to share in the Django documentation

How it works

The extra complexity of the jQuery code is due to it running in the browser, without access to any Django variables.

The code works by attaching to a jQuery event used for every Ajax call. It looks up csrftoken from a cookie stored in the browser, determines whether to send the token, based on the request type and host, and sends the token as a HTTP header, instead of including it in the POST data.