【问题标题】:Add CSRF in Fetch JS for Django在 Fetch JS for Django 中添加 CSRF
【发布时间】:2020-10-06 12:59:15
【问题描述】:

我的 django 模板中有以下 JS 代码:

fetch("http://127.0.0.1:8000/api/endpoint", {
      method: "POST",
      body: $("#form").serializeArray(),
    }).then(function(data) {
    });

在 api/endpoint 中,我得到了:

Forbidden (CSRF token missing or incorrect.): /api/endpoint

如何在 fetch 中添加 csrf 令牌?

【问题讨论】:

    标签: javascript django fetch


    【解决方案1】:

    我在一个类似的项目中遇到了几个小时的问题。我终于找到了解决方案!我希望这个信息帮助。我使用的脚本不在 django 模板上,所以使用 csrfmiddlewaretoken: '{{ csrf_token }}' 对我不起作用。

    我在上面列出的"credentials": 'same-origin'中添加了,还包括了"X-CSRFToken": getCookie("csrftoken"),它使用了底部包含的功能。这是我需要的第二点。所以你的代码应该是这样的:

    fetch("http://127.0.0.1:8000/api/endpoint", {
      method: "POST",
      body: $("#form").serializeArray(),
      credentials: 'same-origin',
      headers: {
          "X-CSRFToken": getCookie("csrftoken")
      }
    })
    .then(function(data) {
    })
    .catch(err => console.log(err));
    

    那么你需要添加这个函数:

    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;}
    

    当然,方法必须在同一页面上。取自 Django 文档。 https://docs.djangoproject.com/en/1.11/ref/csrf/#ajax

    我从这篇文章中找到了以下信息: https://stackoverflow.com/a/43943556来自用户Ska

    【讨论】:

      【解决方案2】:

      在你的 body 中,你可以像这样在你的 ajax 请求中传递 csrf 令牌:

      body : {
         // Other stuff
         csrfmiddlewaretoken: '{{ csrf_token }}'
      }
      

      这应该可以解决您的问题。

      编辑:默认情况下,Fetch 在其请求中不包含 Cookie。为此,您需要在 fetch 请求中添加这一行作为 on 选项:

      credentials : 'include' // For Cors
      credentials : 'same-origin' // For same origin requests 
      

      【讨论】:

      • 感谢您的回复!!不幸的是,这对我不起作用,同样的错误
      • @RahulRentash 刚刚进行了编辑,检查它是否有效。
      • 谢谢!你说的编辑是什么意思?您介意编写完整的获取请求代码吗?谢谢!!
      猜你喜欢
      • 2021-03-25
      • 2021-03-10
      • 2017-09-05
      • 2018-05-08
      • 2019-02-14
      • 1970-01-01
      • 2011-04-28
      • 2022-01-12
      • 2020-02-10
      相关资源
      最近更新 更多