How do I pass the CSRF token when using a jQuery post

6,032 views
Skip to first unread message

Tony King

unread,
Nov 7, 2017, 11:55:47 AM11/7/17
to Django users

Hi,

I thought I'd finally understood this but it seems I have not and I've spent far too much time trying to do it myself.

I have a view rendering to the template below, which is displaying a number of buttons that when clicked will execute another Python function in the views.py.  This works fine if I disable the CSRF protection but as I've read this is not good practice, I'm desperately trying to get the token included in POST request.  I thought I'd finally cracked it yesterday having found the sample code in the documentation and indeed it appeared to work until first I tried my project in a different browser and then subsequently cleared the cache of Chrome.

What am I doing wrong here?

I've not included the views.py as I'm assuming the issue is in the JavaScript.


index.html
{% load static %}

<head>
<!-- <script src="{% static 'jquery-3.2.1.min.js' %}"></script> -->
<!-- <script src="static/jquery-3.2.1.min.js"></script> -->
</head>

<script>
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');
$.ajaxSetup({
beforeSend: function(xhr, settings) {
xhr.setRequestHeader("X-CSRFToken", csrftoken);
}
});
</script>

<body>
<div>
<h1 id='hdr_1'>{{ hdr1 }}</h1>
</div>

<table>
<tr>
{% if my_apps_list %}
{% for my_apps in my_apps_list %}
<td>
<button type="button" id="app{{ forloop.counter }}">
<img src="{% static my_apps.app_icon %}" alt="{{ my_apps.app_name }}" height="132" width="192">
</button><br><br>
<script>
$("#app{{ forloop.counter }}").click( function() {
$.post("{% url 'launch' %}",
{'appname': '{{ my_apps.app_name }}',
'apppath': '{{ my_apps.app_path }}',
'appexe': '{{ my_apps.app_exe }}',
'appargs': '{{ my_apps.app_args }}',
'appusr': '{{ my_apps.app_user }}',
'apppwd': '{{ my_apps.app_pwd }}',
'applook4': '{{ my_apps.app_wait4 }}',
'appdelay': '{{ my_apps.app_delay }}',
'appkeys': '{{ my_apps.app_keys }}'
}, function (msg) {
document.getElementById('appstatus').innerHTML = msg;
});
});
</script>
</td>
{% endfor %}
</tr>
</table>

<br>
<p id='appstatus'></p>

{% else %}
<p>No applications are available.</p>
{% endif %}

</body>

Gourav Chawla

unread,
Nov 9, 2017, 12:03:25 AM11/9/17
to Django users
Message has been deleted

Tony King

unread,
Nov 9, 2017, 12:11:52 PM11/9/17
to Django users

Thanks Gourav,

I have it working now and I can even understand it, which is even better.  For anyone interested my revised working solution is below.

I'm sure it would be better practice putting the token into the headers as described in the documentation and elsewhere but I could not get it to work.


{% load static %}

<head>
<!-- <script src="{% static 'jquery-3.2.1.min.js' %}"></script> -->
<!-- <script src="static/jquery-3.2.1.min.js"></script> -->
</head>

<body>
{% csrf_token %}
<div>
<h1 id='hdr_1'>{{ hdr1 }}</h1>
</div>

<table>
<tr>
{% if my_apps_list %}
{% for my_apps in my_apps_list %}
<td>
<button type="button" id="app{{ forloop.counter }}">
<img src="{% static my_apps.app_icon %}" alt="{{ my_apps.app_name }}" height="132" width="192">
</button><br><br>
<script>
$("#app{{ forloop.counter }}").click( function() {
document.getElementById('hdr_1').innerHTML = 'Hello World!';
$.ajax({
url : "{% url 'launch' %}",
type: "POST",
data: { csrfmiddlewaretoken: document.getElementsByName('csrfmiddlewaretoken')[0].value,
appname: '{{ my_apps.app_name }}',
apppath: '{{ my_apps.app_path }}',
appexe: '{{ my_apps.app_exe }}',
appargs: '{{ my_apps.app_args }}',
appusr: '{{ my_apps.app_user }}',
apppwd: '{{ my_apps.app_pwd }}',
applook4: '{{ my_apps.app_wait4 }}',
appdelay: '{{ my_apps.app_delay }}',
appkeys: '{{ my_apps.app_keys }}'},
dataType : "json",
success: function( msg ){
Reply all
Reply to author
Forward
0 new messages