Ajax 帖子从 Django 返回 CSRF 错误

Posted

技术标签:

【中文标题】Ajax 帖子从 Django 返回 CSRF 错误【英文标题】:Ajax post returns CSRF error from Django 【发布时间】:2014-09-03 06:22:41 【问题描述】:

我正在使用 python 3.2 和 Django 1.6。似乎有很多关于这个的问题,但我仍然没有看到我做错了什么。这是html页面:

<script>
    $('#submit').click(function() 
    var str = $('#regForm').serialize();
    $('#result').html("Trying to make account...");
    $( '#btn' ).hide();
    $.post( 'ajax/registerSubmit', str, function( data ) 
    if (data.indexOf("you have been logged in.") >= 0) 
        $( "#result" ).empty().append( data );
        setTimeout(function()
            window.location = '';
        , 500);
    
    else 
        $( "#result" ).append( data );
        $( '#btn' ).show();
    ;
    );
);
</script>
<div id="Form" title="Register Form">
<table cellspacing="10" >
    <form id="regForm" action="">
        % csrf_token %
           <tr>
                <td>Username:</td>
                <td colspan="2"><input type="text" name="username" size= "30" required /></td>
           </tr>
           <tr>
                <td>Password:</td>
                <td colspan="2"><input type="password" name="password1" size= "30" required /></td>
           </tr>
           <tr>
                <td>Password Confirm:</td>
                <td colspan="2"><input type="password" name="password2" size= "30" required /></td>
           </tr>
           <tr>
                <td>Email:</td>
                <td colspan="2"><input type="text" name="email" size= "30" required /></td>
           </tr>
           <tr>
                <td>First Name:</td>
                <td colspan="2"><input type="text" name="firstName" size= "30" required /></td>
           </tr>
           <tr>
                <td>Last Name:</td>
                <td colspan="2"><input type="text" name="lastName" size= "30" required /></td>
           </tr>
           <tr>
                <td>Phone Number:</td>
                <td colspan="2"><input type="tel" name="phone" size= "30" placeholder="##########" /></td>
           </tr>
           <tr>
                <td>Epa Emts Number:</td>
                <td colspan="2"><input type="text" name="epaemtsNumber" size= "30" placeholder="Optional" /></td>
           </tr>
    </form>
</table>
<div id="result"></div>
<div id="btn">
    <button id="submit">Submit</button>
</div>

这被加载到一个 Jquery 对话框中。当我点击提交时,我收到“POST /trader/ajax/registerSubmit HTTP/1.1”403 2294 错误。使用开发工具,我可以看到实际发送的内容:

在请求头中有这样的:

Cookie: "csrftoken=Xg0AMGcGeMuNhudDnyzZBS7Zc5du10rg;  
         sessionid=7an0o3vq2df6k8qloy1ers37wzt2f2wr"

它说没有发送任何婴儿车。我还可以添加所需的 Django 视图代码。我已经放置了打印语句来查看它有多远,它永远不会到达'ajax/registerSubmit'。

谢谢,

【问题讨论】:

这是一个相关的帖子,也许它可以帮助你:***.com/questions/24663554/django-csrf-403/24671758 【参考方案1】:

您还需要在 AJAX 有效负载中发送 CSRF 令牌,而不仅仅是标头。

鉴于令牌与会话中的令牌相同,常见的模式是 JS 从会话中获取令牌并将其添加到每个 AJAX POST 的有效负载中。

在此处查看操作方法:https://docs.djangoproject.com/en/dev/ref/contrib/csrf/#ajax

【讨论】:

谢谢,这成功了。我之前看到过,但我可以看到它确实有一个 csrf 令牌,所以我认为这就是那个 js 正在做的事情。无论出于何种原因,它都不会使用$('#regForm').serialize() 发送表单数据,所以我必须使用旧的var username = $("input#usernameForm").val();

以上是关于Ajax 帖子从 Django 返回 CSRF 错误的主要内容,如果未能解决你的问题,请参考以下文章

django ajax 发布 403 被禁止

如何在 Django 的 ajax POST 中返回新的 csrf 令牌?

Django - 使用 ExtJS 发布 ajax 请求禁止 403

Django CSRF 令牌错误或缺少 Ajax POST 请求

Django 1.3 中的 Ajax CSRF 问题

即使包含 CSRF 令牌,Laravel ajax 帖子也无法正常工作