这是我的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
文件。我怎样才能让它发挥作用?
答案 0 :(得分:10)
如果要引用模板标记,则需要Django对该文件进行模板化(渲染)。我不建议通过django渲染所有静态文件...
您可以将csrf_token放在一个全局变量中,然后从脚本中访问该变量。你的base.html中有这样的东西:
<script>
var csrftoken = '{{ csrf_token }}';
</script>
或者您可以从javascript文件中的cookie中提取csrftoken。有关解决方案,请参阅this question。该cookie名为csrftoken
。您可以通过打开开发工具并查看域名的Cookie来查看它。
答案 1 :(得分:4)
您可以使用以下功能从客户端的“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>
答案 2 :(得分:2)
CSRF令牌在页面上以cookie的形式提供,名称为“csrftoken”。 Django文档建议获取cookie并将其作为X-CSRFToken
传递到HTTP请求标头中。然后,您可以使用@csrf_protect
装饰器保护视图。
这是关于AJAX的Django文档:https://docs.djangoproject.com/en/dev/ref/contrib/csrf/#ajax。
因此,使用jQuery cookie plugin,您的代码可能如下所示:
$.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) {}
});
答案 3 :(得分:1)
您可以像这样传递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);
}
});
}
}
答案 4 :(得分:0)
参考:https://docs.djangoproject.com/en/dev/ref/csrf/
这是一个最小的例子。
先将您的网址插入html模板。
<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})
答案 5 :(得分:0)
<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,
},
...
})
...
})
})
答案 6 :(得分:0)
您可以简单地在HTML模板中定义它,例如:
<script>
var CSRF_TOKEN = '{{ csrf_token }}';
</script>
它将起作用
答案 7 :(得分:-1)
我已经尝试了许多方法来解决它,下面是总结:
在单独的js文件中使用{{csrf_token}}不能正常工作,前提是您将其嵌入到Django模板中。
在视图中使用@csrf_protect效果不佳,因为它只能保护部分功能。
正确的实施方法在这里:
从django.views.decorators.csrf导入csrf_exempt
然后在查看函数之前,使用@csrf_exempt:这是一个示例
从django.views.decorators.csrf导入csrf_exempt
@csrf_exempt
def function_name(request):
您的功能在这里。
希望有帮助