123👍
You can make AJAX post request in two different ways:
-
To tell your view not to check the csrf token. This can be done by using decorator
@csrf_exempt
, like this:from django.views.decorators.csrf import csrf_exempt @csrf_exempt def your_view_name(request): ...
-
To embed a csrf token in each AJAX request, for jQuery it may be:
$(function () { $.ajaxSetup({ headers: { "X-CSRFToken": getCookie("csrftoken") } }); });
Where the
getCookie
function retrieves csrf token from cookies. I use the following implementation:function getCookie(c_name) { if (document.cookie.length > 0) { c_start = document.cookie.indexOf(c_name + "="); if (c_start != -1) { c_start = c_start + c_name.length + 1; c_end = document.cookie.indexOf(";", c_start); if (c_end == -1) c_end = document.cookie.length; return unescape(document.cookie.substring(c_start,c_end)); } } return ""; }
Also, jQuery has a plugin for accessing cookies, something like that:
// set cookie $.cookie('cookiename', 'cookievalue'); // read cookie var myCookie = $.cookie('cookiename'); // delete cookie $.cookie('cookiename', null);
59👍
The simplest way I have found is to include the {{csrf_token}}
value in the data:
jQuery.ajax(
{
'type': 'POST',
'url': url,
'contentType': 'application/json',
'data': {
'content': 'xxx',
'csrfmiddlewaretoken': '{{ csrf_token }}',
},
'dataType': 'json',
'success': rateReviewResult
}
);
- [Django]-Getting TypeError: __init__() missing 1 required positional argument: 'on_delete' when trying to add parent table after child table with entries
- [Django]-Django : How can I find a list of models that the ORM knows?
- [Django]-What's the best solution for OpenID with Django?
26👍
It took me a while to understand what to do with the code that Daniel posted. But actually all you have to do is paste it at the beginning of the javascript file.
For me, the best solution so far is:
-
Create a
csrf.js
file -
Paste the code in the
csrf.js
file -
Reference the code in the template you need it
<script type="text/javascript" src="{{ STATIC_PREFIX }}js/csrf.js"></script>
Notice that STATIC_PREFIX/js/csrf.js
points to my file. I am actually loading the STATIC_PREFIX
variable with {% get_static_prefix as STATIC_PREFIX %}
.
Advanced tip: if you are using templates and have something like base.html
where you extend from, then you can just reference the script from there and you don’t have to worry anymore in there rest of your files. As far as I understand, this shouldn’t represent any security issue either.
- [Django]-Django: Using F arguments in datetime.timedelta inside a query
- [Django]-CORS error while consuming calling REST API with React
- [Django]-Serializer call is showing an TypeError: Object of type 'ListSerializer' is not JSON serializable?
21👍
Simple and short
$.ajaxSetup({
headers: { "X-CSRFToken": '{{csrf_token}}' }
});
OR
function csrfSafeMethod(method) {
// these HTTP methods do not require CSRF protection
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
$.ajaxSetup({
beforeSend: function(xhr, settings) {
if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
xhr.setRequestHeader("X-CSRFToken", '{{csrf_token}}');
}
}
});
- [Django]-When to create a new app (with startapp) in Django?
- [Django]-Django migration error :you cannot alter to or from M2M fields, or add or remove through= on M2M fields
- [Django]-Django.core.exceptions.ImproperlyConfigured: Error loading psycopg module: No module named psycopg
9👍
For lack of a straight forward answer, you just have to add the header X-CSRFToken
to the ajax request which is in the cookie csrftoken
. JQuery doesn’t do cookies (for some reason) without a plugin so:
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-cookie/1.4.1/jquery.cookie.min.js"></script>
and the minimal code change is:
$.ajax({
headers: { "X-CSRFToken": $.cookie("csrftoken") },
...
});
- [Django]-Do I need Nginx with Gunicorn if I am not serving any static content?
- [Django]-How can I get MINIO access and secret key?
- [Django]-What does this Django regular expression mean? `?P`
6👍
The fastest solution without any plugins if you are not embedding js into your template is:
Put <script type="text/javascript"> window.CSRF_TOKEN = "{{ csrf_token }}"; </script>
before your reference to script.js file in your template, then add csrfmiddlewaretoken
into your data
dictionary:
$.ajax({
type: 'POST',
url: somepathname + "do_it/",
data: {csrfmiddlewaretoken: window.CSRF_TOKEN},
success: function() {
console.log("Success!");
}
})
If you do embed your js into the template, it’s as simple as: data: {csrfmiddlewaretoken: '{{ csrf_token }}'}
- [Django]-How to move a model between two Django apps (Django 1.7)
- [Django]-How can I enable CORS on Django REST Framework
- [Django]-Django: Multiple forms possible when using FormView?
4👍
Thank you everyone for all the answers. I am using Django 1.5.1. I’m a little late to the party, but here goes.
I found the link to the Django project to be very useful, but I didn’t really want to have to include the extra JavaScript code every time I wanted to make an Ajax call.
I like jerrykan’s response as it is very succinct and only adds one line to an otherwise normal Ajax call. In response to the comments below his comment regarding situations when Django template tags are unavailable, how about loading up the csrfmiddlewaretoken from the DOM?
var token = $('input[name="csrfmiddlewaretoken"]').prop('value');
jQuery.ajax({
type: 'POST',
url: url,
data: { 'csrfmiddlewaretoken': token },
dataType: 'json',
success: function(data) { console.log('Yippee! ' + data); }
});
EDIT March 2016
My approach to this issue over the past few years has changed. I add the code below (from the Django docs) to a main.js file and load it on every page. Once done, you shouldn’t need to worry about the CSRF token with ajax again.
function getCookie(name) {
var cookieValue = null;
if (document.cookie && document.cookie != '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = jQuery.trim(cookies[i]);
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) == (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
var csrftoken = getCookie('csrftoken');
- [Django]-Django celery task: Newly created model DoesNotExist
- [Django]-Pass request context to serializer from Viewset in Django Rest Framework
- [Django]-Sort order of Django Admin records
4👍
I got the same issue yesterday and thought it would help people if there were a simple way to handle it, so I wrote a jQuery plugin for that: jquery.djangocsrf. Instead of adding the CSRF token in every request, it hooks itself on the AjaxSend jQuery event and adds the client cookie in a header.
Here’s how to use it:
1- include it:
<script src="path/to/jquery.js"></script>
<script src="path/to/jquery.cookie.js"></script>
<script src="path/to/jquery.djangocsrf.js"></script>
2- enable it in your code:
$.djangocsrf( "enable" );
Django always add the token in a cookie if your template uses {% csrf_token %}
. To ensure it always adds it even if you don’t use the special tag in your template, use the @ensure_csrf_cookie
decorator:
from django.views.decorators.csrf import ensure_csrf_cookie
@ensure_csrf_cookie
def my_view(request):
return render(request, 'mytemplate.html')
Note: I’m using Django 1.6.2.
- [Django]-Django development server reload takes too long
- [Django]-Django model CharField: max_length does not work?
- [Django]-How do I get the class of a object within a Django template?
4👍
Include x-csrftoken
header in request:
var token = $('input[name="csrfmiddlewaretoken"]').prop('value');
jQuery.ajax({
type: 'POST',
url: url,
beforeSend : function(jqXHR, settings) {
jqXHR.setRequestHeader("x-csrftoken", get_the_csrf_token_from_cookie());
},
data: data,
dataType: 'json',
});
- [Django]-Make the first letter uppercase inside a django template
- [Django]-Disable a method in a ViewSet, django-rest-framework
- [Django]-How to reload modules in django shell?
0👍
If, after reading other answers, someone is still struggling please try this:
$.ajax({
type: "POST",
beforeSend: function (request)
{
request.setRequestHeader("X-CSRF-TOKEN", "${_csrf.token}");
},
url: servlet_path,
data : data,
success : function(result) {
console.log("Success!");
}
});
- [Django]-How to produce a 303 Http Response in Django?
- [Django]-How can I unit test django messages?
- [Django]-Django ManyToMany filter()
0👍
Please not that when doing it this way make sure you don’t have the {% csrf_token %}
inside the <form></form>
tags. Then as explained here add the following code to your javascript
function getCookie(name) {
let cookieValue = null;
if (document.cookie && document.cookie !== '') {
const cookies = document.cookie.split(';');
for (let i = 0; i < cookies.length; i++) {
const cookie = cookies[i].trim();
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) === (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
const csrftoken = getCookie('csrftoken');
// using js fetch
// https://docs.djangoproject.com/en/3.1/ref/csrf/#setting-the-token-on-the-ajax-request
const request = new Request(
/* URL */,
{headers: {'X-CSRFToken': csrftoken}}
);
fetch(request, {
method: 'POST',
mode: 'same-origin' // Do not send CSRF token to another domain.
}).then(function(response) {
// ...
});
- [Django]-Django Templating: how to access properties of the first item in a list
- [Django]-How do I filter ForeignKey choices in a Django ModelForm?
- [Django]-Using Django time/date widgets in custom form
0👍
Just want to put it out here that if GET
works in your use case, then it wouldn’t need the CSRF token. For my use case, using GET
was OK.
- [Django]-Django Model Field Default Based Off Another Field in Same Model
- [Django]-Django – iterate number in for loop of a template
- [Django]-Django admin file upload with current model id
0👍
html
<form action="">
{% csrf_token %}
</form>
JS
<script>
const csrftoken = document.querySelector('[name=csrfmiddlewaretoken]').value;
const request = new Request(
'url_here',
{headers: {'X-CSRFToken': csrftoken}}
);
fetch(request, {
method: 'POST',
// mode: 'same-origin' optinal // Do not send CSRF token to another domain.
}).then(function(response) {
console.log(response);
});
</script>
- [Django]-Django vs. Model View Controller
- [Django]-Django edit user profile
- [Django]-Django – Circular model import issue
0👍
As a summary for my mistakes:
- Don’t forget to set the request content type.
- Get the csrf value, either from
- The template
{{ csrf_token }}
- The cookie, use the snippet in django site
NB. The default cookie name is
csrftoken
, but can be overriden byCSRF_COOKIE_NAME
setting.- The DOM, if you can’t access the cookie (you set CSRF_USE_SESSIONS or CSRF_COOKIE_HTTPONLY to True)
document.querySelector(‘[name=csrfmiddlewaretoken]’).value;
- The template
- Set the request header, I’am using XMLHttpRequest
const Http = new XMLHttpRequest();
Http.setRequestHeader("X-CSRFToken", CSRF_VALUE);
Http.setRequestHeader("X_CSRFTOKEN", CSRF_VALUE);
The header name is managed by
CSRF_HEADER_NAME
setting, which its default isHTTP_X_CSRFTOKEN
.
But: "The header name received from the server is normalized by converting all characters to uppercase, replacing any hyphens with underscores, and adding an ‘HTTP_’ prefix to the name" src.
So, If you set the HTTP_X_CSRFTOKEN
header, Django will convert it to HTTP_HTTP_X_CSRFTOKEN
which wis incorrect name and will raise CSRF missed
error.
Http.setRequestHeader("X-CSRFToken", csrftoken); // This worked
Http.setRequestHeader("X-CSRFTOKEN", csrftoken); // Also this
Http.setRequestHeader("HTTP-X-CSRFToken", csrftoken); // Not working
Http.setRequestHeader("HTTP_X_CSRFTOKEN", csrftoken); // Not Working
Http.setRequestHeader("X_CSRFTOKEN", csrftoken); // Not working !!
-
Don’t use url in ajax that is different than that of the browser
127.0.0.1
&localhost
are not the same !! -
No need to set
data.append("csrfmiddlewaretoken", csrftoken);
in the request body, As I know.
- [Django]-Django model object with foreign key creation
- [Django]-What does this Django regular expression mean? `?P`
- [Django]-Django using get_user_model vs settings.AUTH_USER_MODEL