即使我使用了csrf_token,Ajax也不起作用

时间:2017-03-11 07:16:23

标签: jquery ajax django

我有一个使用django的网页游戏项目

首先,当我使用ajax-get方法带来用户角色数据时,

它工作正常

(function(){
    $("document").ready(function(){

        $get_id = $('#character');

        //현재 로그인 된 유저가 케릭터를 갖고 있는지 확인하는 코드
        $user_has_character = $(".data").data("hasCharacter");


        /*****************************
         * when user have character
         * ***************************/
        if($user_has_character=="True"){

            get_gamestart_api_url = '/api/gamestart/data/';

            //게임 화면 태그
            $scene = $('#scene');

            $scene.css("background", "url(../static/images/game/loadingBackground.jpg) no-repeat");

        /*****************************
         * 
         * json will get user's character data
         * 
         * **************************/
        $.ajax({

            method:'GET',
            url:get_gamestart_api_url,

        }).done(function(data){
                character = data[0].character[0]
                $get_id.append("<li class='stat'> 케릭터 닉네임: "+character.nickname+"</li>",
                    "<li class='stat'> 케릭터 레벨: "+character.level+"</li>",
                    "<li class='stat'> 케릭터 직업: "+character.job+"</li>",
                    "<li class='stat'> 케릭터 공격력: "+character.status.attack_point+"</li>",
                    "<li class='stat'> 케릭터 수비력: "+character.status.defence_point+"</li>",
                    "<li class='stat'> 케릭터 체력: "+character.status.health+"</li>",
                    "<li class='stat'> 케릭터 마나: "+character.status.mana+"</li>",
                    );
            });


    }else{
        /*********************
         * When the user does not have a character
         ********************/

    }

});
})();

所以,我认为$ .ajax没有任何问题,

when user doesn't have character, user must create a character

}else{
     /*********************
     * When the user does not have a character
     ********************/

        //form tag will created
        $get_id.append("<form method='post' action='/'> <input name='nickname' type='text' style='border: 1px solid #ff0000;'><input type='submit' class='btn_character'> </form>");

        $btn_character = $(".btn_character");
        console.log($btn_character);

        //when user click create user button
        $btn_character.on("click", function(event){

            //using jQuery
            function getCookie(name) {
                var cookieValue = null;
                if (document.cookie && document.cookie !== '') {
                    var cookies = document.cookie.split(';');
                    for (var i = 0; i < cookies.length; i++) {
                        var cookie = jQuery.trim(cookies[i]);
                        // Does this cookie string begin with the name we want?
                        if (cookie.substring(0, name.length + 1) === (name + '=')) {
                            cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                            break;
                        }
                    }
                }
                return cookieValue;
            }
            var csrftoken = getCookie('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);
                    }
                }
            });

            //get input text nickname
            $nickname = $("input[name=nickname]").val();

            $.ajax({
                method:'POST',
                url:'/api/user/characters/',
                data:{
                    nickname:$nickname
                },
            });
        });

    }

即使我使用jquery csrf_token,当发送$ .ajax帖子时, 它显示错误

Forbidden (CSRF token missing or incorrect.): /

但是我无法理解代码中的问题......

1 个答案:

答案 0 :(得分:0)

假设此script位于您的HTML 内,而不在外部.js 文件中,您可以重写此内容:

$get_id.append("<form method='post' action='/'> <input name='nickname' type='text' style='...'><input type='submit' class='btn_character'> </form>");

到此:

$get_id.append("<form method='post' action='/'>{% csrf token %} <input name='nickname' type='text' style='...'><input type='submit' class='btn_character'> </form>");

当您向Django发送POST数据时,您必须将csrf token与其他表单数据一起发布。这是导致错误的原因。

csrf_token由服务器生成,并作为表单内的隐藏输入注入。

如果此脚本存在于自己的文件中,并将其加载到HTML中,请执行以下操作:<script src="path/to/the/script.js"></script>,那么您有两个选项:

  1. 而不是以这种方式加载它,{% include %}它,以便Django可以呈现此值。例如,您应该将其保存(包括<script></script>标记!)为game_script.html。然后在你的HTML模板中注入它:

    <body> staf here and ... ... at the bottom {% include 'game_script.html' %} </body>

  2. 另一个选项是在动态创建表单之前,向服务器发出另一个AJAX请求以获取csrf token,一旦获得它,然后创建表单(在append内)包括您收到的csrf_token

  3. 但最简单的解决方案不是向Django发出POST请求,而是向GET发出method='post'请求。只需将method='get'更改为csrf tokens,就可以了。没有<?php login(); function connectToDatabase(){ $connection=mysqli_connect("localhost","user","pass","db"); if (mysqli_connect_errno()) { echo "Failed to connect to MySQL: " . mysqli_connect_error(); } mysqli_set_charset($connection,"utf8"); return $connection; } function login(){ $connection = connectToDatabase(); $Username = $_REQUEST['Username']; $Pass = $_REQUEST['Pass']; if($Username!="" && $Pass!=""){ $result = mysqli_query($connection,"select count(*) from user where usr_name='$Username' and usr_password='$Pass'"); $row = mysqli_fetch_array($result); if($row[0]>=1){ print "yes_user"; }else if($row[0]<=0){ print "no_user"; } mysqli_close($connection); }else { print "null"; } } ?> 需要它。