Django ajax POST 扩展用于 CSRF 保护的 beforeSend 方法

Posted

技术标签:

【中文标题】Django ajax POST 扩展用于 CSRF 保护的 beforeSend 方法【英文标题】:Django ajax POST extend beforeSend method used for CSRF protection 【发布时间】:2013-09-16 15:37:40 【问题描述】:

我确实需要在 Django 中进行相同的 ajax POST 调用。所以我使用 Django 文档中描述的方法:

function csrfSafeMethod(method) 
    return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));

$.ajaxSetup(
    crossDomain: false, 
    beforeSend: function(xhr, settings) 
        if (!csrfSafeMethod(settings.type)) 
            xhr.setRequestHeader("X-CSRFToken", csrftoken);
        
    
);

但是,当我进行 ajax 调用并想为 beforeSend 方法添加一些操作(即显示加载器图像)时,它会删除上述功能。示例:

$.ajax(
    url: "some_url",
    type: "POST",
    data: some_form.serialize(),
    beforeSend: function()  some_element.showLoader();
);
$.ajax(
    url: "some_other_url",
    type: "POST",
    data: some_other_form.serialize(),
    beforeSend: function()  some_other_element.showLoader();
);

DRY 很重要,我不想将“showLoader()”函数放在 ajaxSetup 中,因为它可能会有所不同。

【问题讨论】:

【参考方案1】:

好吧,没关系,我找到了解决方案。只需使用 ajaxSend():

$(document).ajaxSend(function(event, xhr, settings)
    if (!csrfSafeMethod(settings.type)) 
        xhr.setRequestHeader("X-CSRFToken", csrftoken);
    
);

【讨论】:

绝对是最好最简单的解决方案!谢谢。【参考方案2】:

$.ajax 中传入的配置会覆盖 $.ajaxsetup 中的配置,所以你可以先调用 global beforesend func 再做自定义作业

$.ajaxSetup(
  crossDomain: false, // obviates need for sameOrigin test
  beforeSend: function(xhr, settings) 
    if (!csrfSafeMethod(settings.type)) 
      xhr.setRequestHeader("X-CSRFToken", $.cookie('csrftoken'));
    
  
);

$.ajax(
    type: "POST",
    url: "url",
    data: data,
    beforeSend : function(xhr, settings)
      //call global beforeSend func
      $.ajaxSettings.beforeSend(xhr, settings);
      //add some custom code below
      $("#spinner").show();
      blah blah blah
    ,
);

【讨论】:

【参考方案3】:

感谢您为 alekwisnia 提供解决方案! 我只是想把解决方案一一展示并解释更多:

添加你的头这个脚本来创建 csrf 令牌:

<script src="https://cdn.jsdelivr.net/npm/js-cookie@beta/dist/js.cookie.min.js"></script>

并使用 ajax 设置功能将 csrf 令牌添加到您的 ajax 请求标头:

<script>
var csrftoken = Cookies.get('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);
    
  
);
$(document).ajaxSend(function(event, xhr, settings)
    if (!csrfSafeMethod(settings.type)) 
        xhr.setRequestHeader("X-CSRFToken", csrftoken);
    
);
</script>

【讨论】:

以上是关于Django ajax POST 扩展用于 CSRF 保护的 beforeSend 方法的主要内容,如果未能解决你的问题,请参考以下文章

Django 表单未使用 Javascript 提交

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

用于 Ajax 的 Django csrf 令牌

django:csrf_token 用于单个页面上的多个表单和 ajax 请求

django基础知识之Ajax:

django之jquery完成ajax