我在使用Django CSRF和Ajax时遇到问题。我得到了一个403 Forbidden。我已经完成了通常使用非ajax请求执行的所有CSRF操作,但我仍然遇到此问题。我认为这与https://docs.djangoproject.com/en/dev/ref/contrib/csrf/#ajax的javascript代码段有关。
$(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'));
}
});
我目前没有使用这个片段,主要是因为我不理解它的一个词,我不知道如何将它合并到我的jquery ajax调用中:
function submit_search()
{
$.ajax({
data: {query: document.search_form.query.value},
datatype: 'json',
success: function(data, textStatus, XMLHttpRequest)
{
if (data)
{
if (check_authentication(data))
{
$("#results").html("");
var results = data[0];
var length = data[1];
for (var index = 0; index < results.length; ++index)
{
var result = results[index];
$("#results").append("<p><a href='/entities/" + result["id"] + "'>" + result["name"] +
"</a><br />" + result["description"] + "</p>");
}
}
else
{
offer_login();
}
}
},
type: 'POST',
url: '/ajax/search',
});
}
有谁知道我应该如何将此代码段添加到我的代码中?
也尝试过:
$.ajaxSetup({
beforeSend: function(xhr, settings) {
if (!(/^http:.*/.test(settings.url) || /^https:.*/.test(settings.url))) {
// Only send the token to relative URLs i.e. locally.
xhr.setRequestHeader("X-CSRFToken",
$("#csrfmiddlewaretoken").val());
}
}
});
但这似乎也不起作用,虽然我不确定我是否应该为我的表格中的#csrfmiddlewaretoken做点什么
由于
答案 0 :(得分:3)
您需要做的就是粘贴代码块,使其中的代码运行。如果你有一个全局的JS文件,你应该只能将JavaScript添加到所述文件的末尾,它将解决问题。
答案 1 :(得分:1)
以及https://docs.djangoproject.com/en/dev/ref/contrib/csrf/
中所述的步骤总结繁琐的django doc,你需要: 1.安装jquery.cookie插件 2.确保crsf_token传递
例如,在您的模板中,表单必须包含以下隐藏字段
<input type="hidden" name="csrfmiddlewaretoken" value="{{csrf_token}}"/>
在你的ajax请求中,你应该像
这样类似的东西csrf_token = $.cookie('csrftoken');
$.ajax({
url: '/url/',
type: 'POST',
beforeSend: function(xhr, settings) {
xhr.setRequestHeader("X-CSRFToken", csrf_token);
},
data: $('.form').serialize(), //assume you are submit a form
}).done(function(response){
console.log(response)
});
您可能缺少的一个小技巧是,您的目标网页(非ajax)需要@csrf_protect装饰器来设置Cookie,如果您不这样做,则Cookie不会存在且该方法将失败。如果您不想做@csrf_protect装饰器,您可以随时返回文档并专门设置cookie。无论哪种方式都可行。
希望这有帮助。