Last active
December 25, 2015 22:09
-
-
Save richtier/7048051 to your computer and use it in GitHub Desktop.
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."
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(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 -- api.jquery.com/jQuery.ajaxSetup/ | |
// send the request | |
$.post(url, {}, 'json') //docs -- api.jquery.com/jQuery.post/ | |
.done(function(data){ | |
// do stuff on success | |
}) | |
.fail(function(){ | |
//do stuff on fail | |
}) | |
.always(function(){ | |
// 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 = document.location.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 + '/') || | |
!(/^(\/\/|http:|https:).*/.test(url)); | |
} | |
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