Skip to content

Instantly share code, notes, and snippets.


richtier/ajax and CSRF

Last active Dec 25, 2015
What would you like to do?
I was asked "I am running into the 403 forbidden issue with django and ajax and was wondering if you could help me a little."
(note, the concept definitely works, but the implementation may have some bug, spelling mistakes etc).
Your problem is your request is missing the Cross Site Request Forgery token (CSRF).
This is a precaution django provide automatically to prevent others doing nefarious stuff.
Non-POST requests don't need the CSRF token, but for POST we need to do some magic:
we need to pass the CSRF token from django to javascript. This is best done like so:
In django:
from django.middleware.csrf import get_token
csrf_token = get_token(self.request) # this is the CSRF token. pass it to your base template.
In your base tample:
/* see this as a html "dictionary" that is middleground between django and js, remember its a bad practice to put js in html file */
<div id="django-data" data-CSRF="{{csrf_token}}"/>
In javascript:
var csrf_token = $("#django-data").data().CSRF;
// note POST method does not cache
$.ajaxSetup({timeout: 2000, }); // docs --
// send the request
$.post(url, {}, 'json') //docs --
// do stuff on success
//do stuff on fail
// do stuff after either dail or success
// this automatically intercepts each ajax request, checks if it is going to
// your server, and adds the csrf token if so:
$(document).ajaxSend(function(event, xhr, settings) {
function sameOrigin(url) {
var host =,
protocol = document.location.protocol,
sr_origin = '//' + host,
origin = protocol + sr_origin;
return (url == origin || url.slice(0, origin.length + 1) == origin + '/') ||
(url == sr_origin || url.slice(0, sr_origin.length + 1) == sr_origin + '/') ||
function safeMethod(method) {
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
if (!safeMethod(settings.type) && sameOrigin(settings.url)) {
xhr.setRequestHeader("X-CSRFToken", csrf_token);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment