【问题标题】:JQuery AJAX BeforeSend CSRF ProtectionJQuery AJAX BeforeSend CSRF 保护
【发布时间】:2017-10-21 00:02:04
【问题描述】:

我有一个显示 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

标签: jquery ajax flask wtforms flask-wtforms


【解决方案1】:

我建议你移动 event.preventDefault();在事件提交之后也使用console.log,这样你就可以检查变量是否包含你的想法,控制台在你的浏览器中只是谷歌如何在浏览器中打开你的控制台,这样你就可以检查包含csrf_token的内容以及长度和数据在 "done" aa 的响应中添加 .fail 以便您可以处理有错误的服务器响应。

关于以下问题:“我需要在“.done”之前添加分号吗?答案是否定的,因为这称为方法链接示例: $("#id").show().css("background", "red");在示例中,即时链接显示和 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);
        });             
    });

});

【讨论】:

  • 您好马丁,非常感谢您的回复。我非常感激。我已经尝试过这个脚本,稍微修改了一下,但是我无法让它工作。我不要求您以任何方式更新脚本,只是注意到我的解决方案在我的场景中不起作用。可能是用户问题,我没有在 JQuery 上投入太多时间。在这个 AJAX 电话会议上发生了这么多事情,这是我断断续续的……好几个星期了。粉碎。再次感谢!!!!
  • 但是……你用我写的脚本检查了控制台吗?
  • 报告“ReferenceError: csrftoken is not defined”
  • 你把下划线 :V 放在哪里了?
  • xhr.setRequestHeader("X-CSRFToken", csrftoken) //必须是你定义的csrf_token ;)
猜你喜欢
  • 2013-09-16
  • 2012-02-03
  • 2013-04-09
  • 2011-10-26
  • 2019-01-25
  • 2015-10-06
  • 2017-06-14
  • 2019-07-14
  • 2023-03-08
相关资源
最近更新 更多