![](/img/trans.png)
[英]How to properly append django csrf_token to form in inline javascript?
[英]how to pass csrf_token to javascript file in django?
這是我的 javascript 代碼,運行良好。 但我喜歡將 javascript 文件分開,而不是用作內聯腳本標簽
<script>
$('.book').click(function() {
var id= $(this).attr('id');
data={
'id':id,
'csrfmiddlewaretoken':'{{ csrf_token }}',
};
$.ajax({
url: '/post/book/',
cache:'false',
dataType:'json',
type:'POST',
data:data,
success: function(data){
//do something
else {
//do something
}
},
error: function(error){
alert('error; '+ eval(error));
}
});
return false;
});
});
</script>
我想將它包含在我的 base.html 中的 custom.js 文件中。 這是
{% load static from staticfiles %}
{% load bootstrap3 %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{% block title %}{% endblock %}</title>
{% bootstrap_css %}
<!-- Optional theme -->
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap-theme.min.css">
<link href="{% static "css/custom.css" %}" rel="stylesheet">
<!-- Latest compiled and minified JavaScript -->
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script src="http://ajax.aspnetcdn.com/ajax/jquery.dataTables/1.9.4/jquery.dataTables.js"></script>
<script src="{% static "js/custom.js" %}" ></script>
<script src="{% static "js/jquery.blockUI.js" %}"></script>
{% bootstrap_javascript %}
{% load bootstrap3 %}
{% load static from staticfiles %}
{% block content %} {% endblock %}
我無法將 Django 中當前模板中可用的csrf_token
引用到static js
文件。 我怎樣才能讓它工作?
如果您想引用模板標簽,那么您需要該文件由 Django 模板化(呈現)。 而且我不建議通過 django 渲染所有靜態文件...
您可以將 csrf_token 放在一個全局變量中,然后您可以從腳本訪問該變量。 在你的 base.html 中是這樣的:
<script>
var csrftoken = '{{ csrf_token }}';
</script>
或者,您可以從 javascript 文件中的 cookie 中提取 csrftoken。 請參閱此問題以獲取解決方案。 該 cookie 稱為csrftoken
。 您可以通過打開開發工具並查看域的 cookie 來查看它。
您可以使用以下函數從客戶端的“csrftoken”cookie 訪問 CSRF 令牌:
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 = 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;
}
並稱之為:
getCookie('csrftoken');
或者您可以簡單地在 HTML 模板中定義一個變量並在您的客戶端腳本中使用它。
<script>
var CSRF_TOKEN = '{{ csrf_token }}';
</script>
CSRF 令牌可用作頁面上名為“csrftoken”的 cookie。 Django 文檔建議獲取 cookie 並將其作為X-CSRFToken
在 HTTP 請求標頭中X-CSRFToken
。 然后您可以使用@csrf_protect
裝飾器保護視圖。
以下是 AJAX 上的 Django 文檔: https : //docs.djangoproject.com/en/dev/ref/contrib/csrf/#ajax 。
因此,使用jQuery cookie 插件,您的代碼可能如下所示:
$.ajax({
url: '/post/book/',
cache: 'false',
dataType: 'json',
type: 'POST',
data: data,
beforeSend: function(xhr) {
xhr.setRequestHeader('X-CSRFToken', $.cookie('csrftoken')),
},
success: function(data) {},
error: function(error) {}
});
在 Django 2.x 參考: https : //docs.djangoproject.com/en/2.2/ref/csrf/
這是一個最小的例子。
首先在 html 模板中插入你的 url。
<input type="hidden" id="u_calc" data-url="{% url 'demo:calc' %}"/>
然后,從 cookie 中獲取您的 url 和 csrf 令牌。 在ajax請求中使用beforeSend
。
let u_calc = $("#u_calc").attr("data-url");
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 = 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;
}
var csrftoken = getCookie('csrftoken');
function csrfSafeMethod(method) {
// these HTTP methods do not require CSRF protection
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
function get_result(number) {
let n = number.val();
$.ajax({
beforeSend: function (xhr, settings) {
if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
xhr.setRequestHeader("X-CSRFToken", csrftoken);
}
},
method: "POST",
type: "POST",
url: u_calc,
async: true,
dataType: "json",
data: JSON.stringify({'number': n}),
contentType: "application/json",
success: function (data) {
alert(data.result);
},
});
}
在views.py
, calc
函數可能看起來像
def calc(request):
if request.is_ajax() and request.method == "POST":
data = json.loads(request.body)
number = int(data["number"])
return JsonResponse({"result": 2 * number})
你可以像這樣傳遞csrf_token
function deleteAccount(id, name) {
if (confirm('Do you want to delete ' + name + '?')) {
$.ajax({
type: 'post',
url: url,
data: 'csrfmiddlewaretoken={{csrf_token}}',
success: function() {
window.location.reload(true);
}
});
}
}
<button id="check_button" data-csrf="{{ csrf_token }}">
button
</button>
$(document).ready(function() {
$('#check_button').click(async function() {
await fetch(url, {
method: 'POST',
headers: {
'X-CSRFToken': $(this).data().csrf,
},
...
})
...
})
})
您可以簡單地在 HTML 模板中定義它,例如:
<script>
var CSRF_TOKEN = '{{ csrf_token }}';
</script>
它會工作
我已經嘗試了很多方法來解決它,這里是回顧:
在單獨的 js 文件中使用 {{ csrf_token }} 不起作用,您將其嵌入到 django 模板中。
在您的視圖中使用 @csrf_protect 效果不佳,因為它只能保護部分功能。
正確的實現方法在這里:
從 django.views.decorators.csrf 導入 csrf_exempt
然后在視圖函數之前,使用@csrf_exempt:這里是一個例子
從 django.views.decorators.csrf 導入 csrf_exempt
@csrf_exempt
定義函數名稱(請求):
你的功能在這里。
希望有幫助
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.