我正在通过'Django 1.0网站开发'工作,并在使用表单时遇到问题。服务器抱怨有关'csrf'的事情。我可以在form-tag之后添加{% csrf_token %}
来解决它。我已经阅读了djangoproject.com上的文档,但我不得不承认我并不完全理解这里到底发生了什么。我不使用中间件类。
当我到达ajax时,真正的问题就开始了。我按照书中的说明写信,但服务器开始抱怨:
"POST /save/?ajax HTTP/1.1" 403 2332
以下是可能导致问题的代码:
function bookmark_save() {
var item = $(this).parent();
var data = {
url: item.find("#id_url").val(),
title: item.find("#id_title").val(),
tags: item.find("#id_tags").val()
};
$.post("/save/?ajax", data, function (result) {
if (result != "failure") {
item.before($("li", result).get(0));
item.remove();
$("ul.bookmarks .edit").click(bookmark_edit);
}
else {
alert("Failed to validate bookmark before saving.");
}
});
return false;
}
'/ save /& amp; ajax'由
处理if ajax:
return render_to_response('bookmark_save_form.html', variables)
这里是bookmark_save_form.html:
<form id="save-form" method="post" action="/save/">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="save" />
</form>
据我所知,我必须通过POST请求传递csrf_token。但我不知道如何。
对此的任何建议都会很棒。
答案 0 :(得分:1)
我目前正在编写本书,并遇到了完全相同的问题,BTW。不是第一次!基本上发生的事情是没有通过Ajax请求传递csrf令牌。所以,简短而简单的答案是你需要包含csrf令牌是你的ajax调用。这是通过以下代码块完成的:https://docs.djangoproject.com/en/1.3/ref/contrib/csrf/#ajax
jQuery(document).ajaxSend(function(event, xhr, settings) {
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;
}
function sameOrigin(url) {
// url could be relative or scheme relative or absolute
var host = document.location.host; // host + port
var protocol = document.location.protocol;
var sr_origin = '//' + host;
var origin = protocol + sr_origin;
// Allow absolute or scheme relative URLs to same origin
return (url == origin || url.slice(0, origin.length + 1) == origin + '/') ||
(url == sr_origin || url.slice(0, sr_origin.length + 1) == sr_origin + '/') ||
// or any other URL that isn't scheme relative or absolute i.e relative.
!(/^(\/\/|http:|https:).*/.test(url));
}
function safeMethod(method) {
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
if (!safeMethod(settings.type) && sameOrigin(settings.url)) {
xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'));
}
});
然后我将其作为.js文件包含在我的user_page.html中。在那之后,我可以不受惩罚地进行Ajax调用!
答案 1 :(得分:0)
我从已经完成的项目中提取了这个。这是一个联系表单模板。请注意,这是django。另请参阅django书http://www.djangobook.com/en/2.0/。本书回答了我的所有问题。它遍及一切。这显示了如何放入csrf令牌(在模板中):
<head>
<title>Contact Us</title>
</head>
<body>
<h1>Contact us</h1>
{% if form.errors %}
<p style="color: red;">
Please correct the error{{ form.errors|pluralize }} below.
</p>
{% endif %}
<form action="" method="post">
{% csrf_token %}
<ul>
{{ form.as_ul }}
</ul>
<input type="submit" value="Submit">
</form>
</body>
此外,将您的值更改为提交而不是保存,而不是/ save / for action使用post .....可能会使其正常工作。
答案 2 :(得分:0)
我正在完成这本书并遇到了同样的问题。这是最简单的解决方案,其优点是不会禁用Django的csrf保护,或者必须包含装饰器或者使用'ensure_csrf_cookie'等实用程序。它只是传递令牌:
在您创建的.js文件中,用于保存自定义jquery脚本,将以下对添加到bookmark_save()函数中的“data”var中:
csrfmiddlewaretoken: document.getElementsByName('csrfmiddlewaretoken')[0].val()
因此得到的bookmark_save函数如下所示:
function bookmark_save() {
var item = $(this).parent();
var data = {
url: item.find("#id_url").val(),
title: item.find("#id_title").val(),
tags: item.find("#id_tags").val(),
csrfmiddlewaretoken: document.getElementsByName('csrfmiddlewaretoken')[0].val()
};
$.post("/save/?ajax", data, function (result) {
if (result != "failure") {
item.before($("li", result).get(0));
item.remove();
$("ul.bookmarks .edit").click(bookmark_edit);
}
else {
alert("Failed to validate bookmark before saving.");
}
});
return false;
}
答案 3 :(得分:0)
来自django.views.decorators.csrf import csrf_exempt
<div id="myDiv" runat="server" ClientIDMode="static" ></div>
答案 4 :(得分:-1)
创建一个Javascript文件。我不知道如何格式化代码 - 抱歉。然后在Jquery之后加载它。
描述here