Django AJAX POST 在 IE、EDGE 等中登录 CSRF 错误
Django AJAX POST login CSRF error in IE, EDGE, etc
我正在使用 Django 1.10。
我想通过 Jquery AJAX 登录,但 CSRF 已设置。
为了通过CSRF检查,我有以下代码(在独立的js文件中)。
/* CSRF-config Start */
$.ajaxSetup({
beforeSend: function(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;
}
if (!(/^http:.*/.test(settings.url) || /^https:.*/.test(settings.url))) {
// Only send the token to relative URLs i.e. locally.
xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'));
}
}
});
$(document).ajaxSend(function( event, xhr, settings ) {
if (settings.type == 'POST' || settings.type == 'PUT' || settings.type == 'DELETE') {
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;
}
if (!(/^http:.*/.test(settings.url) || /^https:.*/.test(settings.url))) {
// Only send the token to relative URLs i.e. locally.
xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'));
}
}
});
/* CSRF-config End */
Chrome 在这里完美运行,登录没有问题。
但是,当我切换到IE、Edge等时出现如下错误:
"""
已禁止(未设置 CSRF cookie。):/login/
[25/Aug/2016 08:58:42] "POST /login/ HTTP/1.1" 403 2857
"""
我的代码似乎根本不起作用。 :(
这里!我想出了一个解决方案。
以下代码应仅写入模板html页面。
不要将它留给独立的 JS 文件。
删除其他相关CSRF AJAXSetup代码以防冲突
<!-- Bla bla bla your login form, input, etc. -->
<script>
$.ajaxSetup({
data: {csrfmiddlewaretoken: '{{ csrf_token }}' },
});
</script>
来自 Django 文档:
If your view is not rendering a template containing the csrf_token template tag, Django might not set the CSRF token cookie.
Read more...
您可以通过以下两种解决方案之一使用现有的静态 JS:
- 确保在模板中包含
{% csrf_token %}
。通常它以表格形式出现,但如果您不使用表格,只需将其放在正文中的某个位置即可。
- 将
@ensure_csrf_cookie
装饰器添加到您的视图函数中。
我过去只在 IE 上遇到过这个问题
我正在使用 Django 1.10。
我想通过 Jquery AJAX 登录,但 CSRF 已设置。
为了通过CSRF检查,我有以下代码(在独立的js文件中)。
/* CSRF-config Start */
$.ajaxSetup({
beforeSend: function(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;
}
if (!(/^http:.*/.test(settings.url) || /^https:.*/.test(settings.url))) {
// Only send the token to relative URLs i.e. locally.
xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'));
}
}
});
$(document).ajaxSend(function( event, xhr, settings ) {
if (settings.type == 'POST' || settings.type == 'PUT' || settings.type == 'DELETE') {
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;
}
if (!(/^http:.*/.test(settings.url) || /^https:.*/.test(settings.url))) {
// Only send the token to relative URLs i.e. locally.
xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'));
}
}
});
/* CSRF-config End */
Chrome 在这里完美运行,登录没有问题。
但是,当我切换到IE、Edge等时出现如下错误:
"""
已禁止(未设置 CSRF cookie。):/login/
[25/Aug/2016 08:58:42] "POST /login/ HTTP/1.1" 403 2857
"""
我的代码似乎根本不起作用。 :(
这里!我想出了一个解决方案。
以下代码应仅写入模板html页面。
不要将它留给独立的 JS 文件。
删除其他相关CSRF AJAXSetup代码以防冲突
<!-- Bla bla bla your login form, input, etc. -->
<script>
$.ajaxSetup({
data: {csrfmiddlewaretoken: '{{ csrf_token }}' },
});
</script>
来自 Django 文档:
If your view is not rendering a template containing the csrf_token template tag, Django might not set the CSRF token cookie. Read more...
您可以通过以下两种解决方案之一使用现有的静态 JS:
- 确保在模板中包含
{% csrf_token %}
。通常它以表格形式出现,但如果您不使用表格,只需将其放在正文中的某个位置即可。 - 将
@ensure_csrf_cookie
装饰器添加到您的视图函数中。
我过去只在 IE 上遇到过这个问题