JQuery AJAX BeforeSend CSRF Protection

3

我有一个展示JSON响应的AJAX流程。如果我禁用CSRF保护,该流程就可以工作。我会收到HTTP 200,并获得JSON响应。

以下是可行的表单:

$(document).ready(function() {

    //AJAX
    $('form').on('submit', function(event) {
        $.ajax({
            data : {
                user : $('#user').val(),
                password : $('#password').val()
            },
            url: '/loginproc',
            type: 'POST'
        })
        .done(function(data) {
            if (data.error) {
              $('#errorAlert').text(data.error).show();
              $('#successAlert').hide();
            }
            else {
              $('#successAlert').text(data.xx).show();
              $('#errorAlert').hide();
            }
        });
         event.preventDefault();
    });

});

这个语法是否正确?在".done"之前需要加分号吗?


我正在使用 Flask-WTForms CSRF 保护,文档中指出:

当发送 AJAX 请求时,请将 X-CSRFToken 标头添加到请求中。例如,在 JQuery 中,您可以配置所有请求发送令牌。

<script type="text/javascript">
    var csrf_token = "{{ csrf_token() }}";

    $.ajaxSetup({
        beforeSend: function(xhr, settings) {
            if (!/^(GET|HEAD|OPTIONS|TRACE)$/i.test(settings.type) && !this.crossDomain) {
                xhr.setRequestHeader("X-CSRFToken", csrf_token);
            }
        }
    });
</script>

使用以下JS代码,我能够得到HTTP 200状态码,但是没有返回任何JSON数据。
$(document).ready(function() {

    $('form').on('submit', function(event) {

        var csrf_token = "{{ csrf_token() }}";

        $.ajaxSetup({
            beforeSend: function(xhr, settings) {
                if (!/^(GET|HEAD|OPTIONS|TRACE)$/i.test(settings.type)) {
                    xhr.setRequestHeader("X-CSRFToken", csrftoken)
                }
            }
        });

        $.ajax({
            data : {
                user : $('#user').val(),
                password : $('#password').val()
            },
            url: '/loginproc',
            type: 'POST'
        })
        .done(function(data) {
            if (data.error) {
              $('#errorAlert').text(data.error).show();
              $('#successAlert').hide();
            }
            else {
              $('#successAlert').text(data.xx).show();
              $('#errorAlert').hide();
            }
        });
         event.preventDefault();
    });

});

这是否正确?我确实收到了HTTP 200,但没有返回JSON数据。JQuery / AJAX让我非常困惑。

问题:

  1. 表单1(没有CSRF的工作表单)在语法上是否正确?
  2. 我不应该使用“ajaxSetup”吗?
  3. 为什么我没有得到JSON数据?我需要在CSRF中包含返回吗?

非常感谢您的帮助和时间。

在语法上正确并且功能正常 2. s


你可以在htaccess文件中启用csrf保护。尝试使用success函数而不是done。 - Brad
1个回答

0

我建议您将event.preventDefault();放在事件提交后面,同时使用console.log,这样您可以检查变量是否包含您想要的内容。控制台在您的浏览器中,只需搜索如何在浏览器中打开控制台,以便您可以检查csrf_token中包含什么以及“done”响应中的长度和数据,并添加.fail以便您可以处理带有错误的服务器响应。

关于问题:“在“.done”之前需要加分号吗?”答案是否定的,因为这被称为方法链接示例:$("#id").show().css("background", "red"); 在这个例子中,我正在链接show和css,您可以一次链接很多方法;)

$(document).ready(function() {

    $('form').on('submit', function(event) {
        event.preventDefault();
        var csrf_token = "{{ csrf_token() }}";
        console.log("csrf_token: ", csrf_token);

        $.ajaxSetup({
            beforeSend: function(xhr, settings) {
                if (!/^(GET|HEAD|OPTIONS|TRACE)$/i.test(settings.type)) {
                    xhr.setRequestHeader("X-CSRFToken", csrftoken)
                }
            }
        });

        $.ajax({
            data : {
                user : $('#user').val(),
                password : $('#password').val()
            },
            url: '/loginproc',
            type: 'POST'
        })
        .done(function(data) {
            console.log("done", data.length, data); 
            if (data.error) {
              $('#errorAlert').text(data.error).show();
              $('#successAlert').hide();
            }
            else {
              $('#successAlert').text(data.xx).show();
              $('#errorAlert').hide();
            }
        })
        .fail(function( jqXHR, textStatus, errorThrown ) {
            console.error("response with error:", jqXHR, textStatus, errorThrown);
        });             
    });

});


你好Martin,非常感谢你的回复。我非常感激。我尝试了这个脚本,稍微调整了一下,但是我无法让它工作。我并不是要求你更新脚本,只是想指出在我的情况下解决方案没有起作用。可能是用户问题,我没有投入太多时间研究JQuery。这个AJAX调用已经困扰我很多周了。真的很难受。再次感谢!!! - Evan
但是...你用我写的脚本检查了控制台吗? - Martin Cisneros Capistrán
报告显示:“ReferenceError: csrftoken未定义” - Evan
你把下划线放在哪里了? :V - Martin Cisneros Capistrán
xhr.setRequestHeader("X-CSRFToken", csrftoken) // 必须是你定义的 csrf_token ;) - Martin Cisneros Capistrán

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接