在 Django 中的 ajax POST 期间被禁止(CSRF 令牌丢失或不正确。)

Posted

技术标签:

【中文标题】在 Django 中的 ajax POST 期间被禁止(CSRF 令牌丢失或不正确。)【英文标题】:Forbidden (CSRF token missing or incorrect.) during ajax POST in Django 【发布时间】:2019-12-14 07:38:34 【问题描述】:

我正在尝试通过 ajax 发送一个 csv 文件和一堆数据,在发送 csrftoken 另一件事时出现禁止(CSRF 令牌丢失或不正确。)错误,我检查了我在代码和 cookie 中获得了不同的令牌,所以我尝试了。 https://docs.djangoproject.com/en/2.2/ref/csrf/ docs 也是如此,但没有运气 你能帮帮我吗,

这里是js代码

$('#upload').click(function()
    console.log('hello');
    var store = $('#id_store').val();
    var kitchen = $('#id_kitchen').val();
    var form = $('.csv').prop('files')[0];
    var csrftoken = $("[name=csrfmiddlewaretoken]").val();
    console.log(store)
    data=
     'csrfmiddlewaretoken':csrftoken,
     'kitchen':kitchen,
     'store':store,
     'csv_file':form,
     
    console.log(data)
    $.ajax(
        url: "url('custom-admin:csv_upload')",
        type: 'POST',
        data: data,
         processData: false,
         contentType:false,
         success: function (data) 
           if(data.status)
            alert(data.message)
           
           elsealert(data.message)
    
    );
    )

html 文件

   <form id="demo-form2" method="post" data-parsley-validate="" class="form-horizontal form-label-left" enctype="multipart/form-data">
   <div class="form-group">
      <input type="hidden" name="csrfmiddlewaretoken" value=" csrf_token ">
      <label class="control-label col-md-3 col-sm-3 col-xs-5"> Store <span
         class="required">*</span>
      </label>
      <div class="col-md-6 col-sm-6 col-xs-12 stores" id="stores">
          form.store 
      </div>
   </div>
   <div class="form-group">
      <label class="control-label col-md-3 col-sm-3 col-xs-5"> Kitchen <span
         class="required">*</span>
      </label>
      <div class="col-md-6 col-sm-6 col-xs-12 kitchen_list" id="kitchen_list">
          form.kitchen 
      </div>
   </div>
   <div class="form-group"  >
      <label class="control-label col-md-3 col-sm-3 col-xs-5" >  Upload File <span
         class="required"></span>
      </label>
      <div class="col-md-6 col-sm-6 col-xs-12 file">
         form.csv_file
         % if form_errors.csv_file %
         <div class="alert alert-danger">form_errors.csv_file</div>
         % endif %
      </div>
   </div>
   <div class="form-group" >
      <div class="col-md-3 col-sm-3 col-xs-12 col-md-offset-3" style="margin-bottom:10px;">
         <button  type="button" class="btn btn-primary upload" id="upload"> Upload </button>
      </div>
   </div>
</form>

forms.py

class CsvImportForm(forms.Form):
    kitchen = forms.ChoiceField(
        widget=forms.Select(attrs=
            'type': "radio",
            'class': "btn btn-primary btn-md",
            'data-parsley-multiple': 'gender'
        )
    )

    store = forms.ChoiceField(
        widget=forms.Select(attrs=
            'type': "radio",
            'class': "btn btn-primary btn-md stores",
            'data-parsley-multiple': 'gender'
        )
    )
    csv_file = forms.FileField(
        required=False,
        widget=forms.FileInput(attrs=
            'type': "file",
            'class':"csv",
            "data-validation": "mime",
            'data-validation-allowing': "csv",
            'data-validation-error-msg-mime': "You can only upload images in (csv)."
        )
    )

【问题讨论】:

当你说你在尝试 Django 文档中的内容时没有运气,你的意思是你仍然得到 CSRF 令牌丢失错误吗?你的问题有点不清楚 你能添加你的代码吗? @DanielHolmes 是的 @Mathyou 我也添加了 JS 代码 【参考方案1】:

尝试使用javascriptFormData 函数。

$('#upload').click(function()  
        var formData = new FormData();
        var csrftoken = $("[name=csrfmiddlewaretoken]").val();
        formData.append('store', $('#id_store').val());
        formData.append('csrfmiddlewaretoken', csrftoken);
        formData.append('kitchen',  $('#id_kitchen').val());
        formData.append('csv_file', $('.csv')[0].files[0]);

    $.ajax(
        url: "url('custom-admin:csv_upload')",
        type: 'POST',
        data: formData,
        processData: false,
        contentType:false,
        success: function (data) 
           if(data.status)
            alert(data.message)
           
           else
            alert(data.message)
           
        
    );
);

【讨论】:

以上是关于在 Django 中的 ajax POST 期间被禁止(CSRF 令牌丢失或不正确。)的主要内容,如果未能解决你的问题,请参考以下文章

如何在Django使用ajax的POST

是否可以在 Django Rest Framework 中的 ajax 请求期间追溯 403 错误?

Ajax 调用数据在 POST 期间未传递给控制器

在 Django 中的 AJAX POST 请求后重新加载模板

Django 如何让ajax的POST方法带上CSRF令牌

django ajax POST 上的 405 错误