【问题标题】:AJAX only works one timeAJAX 只能工作一次
【发布时间】:2018-01-28 09:06:42
【问题描述】:

我做了一个带有登录表单的模式,并通过 POST AJAX 请求提交。我只能登录一次,当我注销并尝试再次登录时,AJAX 请求的错误消息是这样的 (CSRF failed):

Prohibido (403)
Verificación CSRF fallida. Solicitud abortada

只有当我按 F5 刷新整个页面时,才能再次登录。登录成功后,我只刷新标题,而不是整个页面。我的刷新代码是这样的:

$('#update-' + idToUpdate).load(' #' + idToUpdate);

编辑: 我发现 CSRF 令牌仅在成功请求后才有效一次。我必须生成一个新令牌才能使表单再次工作,并且这个令牌只有在我按 F5 刷新整个页面时才会更新,而这正是我不想做的。

这个问题有什么解决办法吗?我不想做 AJAX 请求来更新 CSRF 令牌,这是不安全的。

【问题讨论】:

  • 您能具体说说您是如何创建 CSRF 令牌的吗?是通过模板变量还是通过文档中提到的js函数? docs.djangoproject.com/en/1.11/ref/csrf/#ajax
  • <form ... > </form>{% csrf_token %} 这就是 Django 的工作方式。它相当于一个用令牌隐藏的输入。

标签: jquery ajax django


【解决方案1】:

我找到了解决方案。在成功请求之后,在我的函数$('#update-' + idToUpdate).load(' #' + idToUpdate); 中插入带有 CSRF 令牌的表单的所有 ID。这会对表单进行部分异步 F5 刷新,因此所有 CSRF 令牌都会得到更新,我可以执行新请求。

【讨论】:

    【解决方案2】:

    您可以通过JS自己生成CSRF令牌:

    // using jQuery
    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;
    }
    var csrftoken = getCookie('csrftoken');
    

    这将在您每次调用该函数时创建一个新的 CSRF 令牌,并且您不需要刷新页面。

    欲了解更多信息,请查看:https://docs.djangoproject.com/en/1.11/ref/csrf/#ajax

    【讨论】:

    • 该代码采用当前 CSRF 令牌的值,但不会刷新它或创建一个新值。我尝试使用官方文档中的代码,但它不起作用。该代码与官方文档中出现的另一个代码的目标是从 cookie 中获取令牌的当前值并将其插入 ajax 请求的标头中。如果你想发送新的成功请求,你需要刷新令牌。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-24
    • 2016-05-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多