未设置 Django CSRF cookie:使用 Ajax 跨站点 views.py:main.js:settings.pyPOST 请求:到目前为止我尝试过的:

问题描述

我的代码有两部分,首先是通过简单的 localhost:3000python HTTP server 上运行的前端(无框架/库)和在 Django server 上运行的 localhost:8080 /api/csrf/,这里发生的事情是前端正在向 Django 服务器发出跨站点 POST 请求,但它被禁止(未设置 CSRF cookie。) > 错误。我知道这个问题已经被问过很多次了,但我似乎没有找到解决方案。

我没有像这样在 Django 中请求 POST 调用的任何经验,不是使用 DRF,而是使用我们自己的端点

问题代码:

首先前端应向def get_csrf(request): # print(get_token(request)) return JsonResponse({ 'detail': 'CSRF cookie set','X-CSRFToken': get_token(request) })

发出一个csrf令牌的get请求

views.py:

success: function (response,status,xhr) {
      $('.csrftoken').attr('value',response['X-CSRFToken']);
       setCookie("csrftoken",response['X-CSRFToken']);
}

得到值后,token被分配给cookie和一个隐藏元素通过

main.js:

xhr.getResponseHeader("X-CSRFToken") -> response['X-CSRFToken']

上面的代码工作正常,我们得到了值,一开始,它是这样的,但不起作用,所以我把它改成了:

header:{ 'X-CSRFToken': token}

现在,每当 前端 向后端发出 POST 调用并在 localhost:8080 上运行 Forbidden (CSRF cookie not set.) 403 时,它都会得到 INSTALLED_APPS = [ 'corsheaders,] MIDDLEWARE = [ 'corsheaders.middleware.CorsMiddleware',] CSRF_COOKIE_HTTPONLY = True SESSION_COOKIE_HTTPONLY = True CORS_ALLOWED_ORIGINS = [ "http://localhost:3000","http://127.0.0.1:3000" ]

settings.py

$.ajax({
      type: "POST",headers:{
        'Content-Type': 'application/json','Accept': 'application/json','X-Requested-With': 'XMLHttpRequest','X-CSRFToken': csrftoken,},url: "/api/userdetails/",data: JSON.stringify(somedata),...
      ...
})

POST 请求

# from the hidden element
const csrftoken = document.querySelector('.csrftoken').value;
# from the cookie
const csrftoken = getCCookie('csrftoken');
# from the name
const csrftoken = jQuery("[name=csrfmiddlewaretoken]").val();

到目前为止我尝试过的:

我尝试通过-

获取csrftoken
CSRF_COOKIE_HTTPONLY = True
SESSION_COOKIE_HTTPONLY = True

所有这些都成功检索到值,我可以在请求头标头中看到该值,但 django 仍然说没有 csrftoken 正如文档所说,在设置一个必须从隐藏元素中获取值时使用以下代码时,我再次尝试在没有它的情况下使用它:

function csrfSafeMethod(method) {
  // these HTTP methods do not require CSRF protection
  return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
$.ajaxSetup({
        beforeSend: function(xhr,settings) {
            if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
                xhr.setRequestHeader("X-CSRFToken",csrftoken);
            }
        }

Doc 说也试试这个:

{{1}}

但是这里没有成功的尝试,代码有什么问题?以及我该如何度过难关。

解决方法

您必须在 django html 模板中包含 {% csrf_token %}。这将创建名为“csrfmiddlewaretoken”的隐藏输入 html 标记。

必须在呈现 html 代码后包含设置 var csrftoken = jQuery("[name=csrfmiddlewaretoken]").val(); 的 javascript 代码,否则 var csrftoken 将设置为 null。

<!DOCTYPE html>
<html>
<body>

<form method="post" action="{% url 'django-view-ajax-handle' %}" id="ajax-function-id" name="ajax-function-name">
    {% csrf_token %}
    {{ form }}
    <input type="submit" value="Submit">
</form>

// GET CSRF_TOKEN AFTER HTML
var csrftoken = jQuery("[name=csrfmiddlewaretoken]").val();

<script>
function csrfSafeMethod(method) {
    // these HTTP methods do not require CSRF protection
    return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}

$(document).ready(function () {
  $("#ajax-function-id").submit(function (event) {

    $.ajax({
      type: "POST",url: $('[name="ajax-function-name"]').attr("action"),beforeSend: function(xhr,settings) {
        if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
            xhr.setRequestHeader("X-CSRFToken",csrftoken);
        }
      },success: function (data) {
        // handle_success
      }
    });
    return false;
  });
});
</script>
</body>
</html>

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...