Как добавить CSRF-токен Django в заголовок POST-запроса jQuery?
Я пытаюсь сделать форму Django с динамически предварительно заполненными полями: то есть, когда одно поле (checkin_type
) выбирается из выпадающего меню, остальные поля автоматически заполняются соответствующими данными. С этой целью я хотел бы отправить запрос POST на сервер, как только выбрана выпадающая опция.
До сих пор я пробовал следующий шаблон (следующий https://docs.djangoproject.com/en/2.0/ref/csrf/):
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/js-cookie@2/src/js.cookie.min.js"></script>
<script>
$(document).ready(function(){
var csrftoken = Cookies.get('csrftoken');
$(".auto-submit").change(function() {
$.post({
url: "{% url 'get-checkin-type' %}",
data: $(".auto-submit option:selected").val(),
headers: {
X-CSRFToken: csrftoken
}
})
});
});
</script>
<form action="" method="post">{% csrf_token %}
{% for field in form %}
<div class="{% if field.name == 'checkin_type' %}auto-submit{% endif %}">
{{ field.errors }}
{{ field.label_tag }}
{{ field }}
</div>
{% endfor %}
<input type="submit" value="Send message" />
</form>
Однако, когда я выбираю опцию раскрывающегося списка, я получаю
new:17 Uncaught SyntaxError: Неожиданный токен -
который исходит от X-CSRFToken: csrftoken
линия:
Может кто-нибудь указать мне, что не так с этим кодом? (Я попытался найти его по https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Unexpected_token но до сих пор не смог понять это).
Кстати, из jQuery кажется, что для добавления всех данных запросов $.post () к CSRF-токену можно добавить токен CSRF к запросу POST. data
, но это не похоже на самый элегантный подход для меня, и документы утверждают, что
По этой причине существует альтернативный метод: для каждого XMLHttpRequest установите настраиваемый заголовок X-CSRFToken равным значению токена CSRF.
2 ответа
Вы пропускаете одиночную кавычку, попробуйте как следует.
$(".auto-submit").change(function() {
$.post({
url: "{% url 'get-checkin-type' %}",
data: $(".auto-submit option:selected").val(),
headers: {
'X-CSRFToken': csrftoken
}
})
});
Решение PSK работает, но ради полноты, вот подход, изложенный в Django docs после прочтения немного дальше (из https://docs.djangoproject.com/en/2.0/ref/csrf/), который использует .ajaxSetup
чтобы покрыть все запросы раз и навсегда:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/js-cookie@2/src/js.cookie.min.js"></script>
<script>
$(document).ready(function(){
var csrftoken = Cookies.get('csrftoken');
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", csrftoken);
}
}
});
$(".auto-submit").change(function() {
$.post({
url: "{% url 'get-checkin-type' %}",
data: $(".auto-submit option:selected").val(),
})
});
});
</script>