使用 fetch post 请求进行正确的 Django CSRF 验证
Proper Django CSRF validation using fetch post request
我正在尝试使用 JavaScript 的 fetch 库向我的 Django 应用程序提交表单。但是无论我做什么,它仍然会抱怨 CSRF 验证。
Ajax 上的文档提到指定 a header 我已经尝试过了。
我也试过抓取 the token from the templatetag 并将其添加到表单数据中。
这两种方法似乎都不起作用。
这是包含表单值和 header 的基本代码:
let data = new FormData();
data.append('file', file);;
data.append('fileName', file.name);
// add form input from hidden input elsewhere on the page
data.append('csrfmiddlewaretoken', $('#csrf-helper input[name="csrfmiddlewaretoken"]').attr('value'));
let headers = new Headers();
// add header from cookie
const csrftoken = Cookies.get('csrftoken');
headers.append('X-CSRFToken', csrftoken);
fetch("/upload/", {
method: 'POST',
body: data,
headers: headers,
})
我可以使用 JQuery 进行此操作,但想尝试使用 fetch
。
想通了。问题是 fetch
doesn't include cookies by default.
简单的解决方案是将 credentials: "same-origin"
添加到请求中并且它有效(使用表单字段但没有 headers)。这是工作代码:
let data = new FormData();
data.append('file', file);;
data.append('fileName', file.name);
// add form input from hidden input elsewhere on the page
data.append('csrfmiddlewaretoken', $('#csrf-helper input[name="csrfmiddlewaretoken"]').attr('value'));
fetch("/upload/", {
method: 'POST',
body: data,
credentials: 'same-origin',
})
你的问题已经很接近成功了。如果您不想要表单方法,这里有一个 json 方法。顺便说一句,@Cory 的表单方法非常简洁。
- 第三个图书馆的巧妙方式
let data = {
'file': file,
'fileName': file.name,
};
// You have to download 3rd Cookies library
// https://docs.djangoproject.com/en/dev/ref/csrf/#ajax
let csrftoken = Cookies.get('csrftoken');
let response = fetch("/upload/", {
method: 'POST',
body: JSON.stringify(data),
headers: { "X-CSRFToken": csrftoken },
})
2。
另一种繁琐的方式,但没有任何第三库
let data = {
'file': file,
'fileName': file.name,
};
let csrftoken = getCookie('csrftoken');
let response = fetch("/upload/", {
method: 'POST',
body: JSON.stringify(data),
headers: { "X-CSRFToken": csrftoken },
})
// The following function are copying from
// https://docs.djangoproject.com/en/dev/ref/csrf/#ajax
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;
}
我正在尝试使用 JavaScript 的 fetch 库向我的 Django 应用程序提交表单。但是无论我做什么,它仍然会抱怨 CSRF 验证。
Ajax 上的文档提到指定 a header 我已经尝试过了。
我也试过抓取 the token from the templatetag 并将其添加到表单数据中。
这两种方法似乎都不起作用。
这是包含表单值和 header 的基本代码:
let data = new FormData();
data.append('file', file);;
data.append('fileName', file.name);
// add form input from hidden input elsewhere on the page
data.append('csrfmiddlewaretoken', $('#csrf-helper input[name="csrfmiddlewaretoken"]').attr('value'));
let headers = new Headers();
// add header from cookie
const csrftoken = Cookies.get('csrftoken');
headers.append('X-CSRFToken', csrftoken);
fetch("/upload/", {
method: 'POST',
body: data,
headers: headers,
})
我可以使用 JQuery 进行此操作,但想尝试使用 fetch
。
想通了。问题是 fetch
doesn't include cookies by default.
简单的解决方案是将 credentials: "same-origin"
添加到请求中并且它有效(使用表单字段但没有 headers)。这是工作代码:
let data = new FormData();
data.append('file', file);;
data.append('fileName', file.name);
// add form input from hidden input elsewhere on the page
data.append('csrfmiddlewaretoken', $('#csrf-helper input[name="csrfmiddlewaretoken"]').attr('value'));
fetch("/upload/", {
method: 'POST',
body: data,
credentials: 'same-origin',
})
你的问题已经很接近成功了。如果您不想要表单方法,这里有一个 json 方法。顺便说一句,@Cory 的表单方法非常简洁。
- 第三个图书馆的巧妙方式
let data = {
'file': file,
'fileName': file.name,
};
// You have to download 3rd Cookies library
// https://docs.djangoproject.com/en/dev/ref/csrf/#ajax
let csrftoken = Cookies.get('csrftoken');
let response = fetch("/upload/", {
method: 'POST',
body: JSON.stringify(data),
headers: { "X-CSRFToken": csrftoken },
})
2。 另一种繁琐的方式,但没有任何第三库
let data = {
'file': file,
'fileName': file.name,
};
let csrftoken = getCookie('csrftoken');
let response = fetch("/upload/", {
method: 'POST',
body: JSON.stringify(data),
headers: { "X-CSRFToken": csrftoken },
})
// The following function are copying from
// https://docs.djangoproject.com/en/dev/ref/csrf/#ajax
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;
}