Cannot unpack request JSON with CSRF on

时间:2017-08-30 20:12:25

标签: jquery ajax python-3.x flask csrf

Ajax request can be unpacked as long as mvn compile is set. As soon as I comment it out, mvn clean compile fails. Putting it through debugger: <?php // test variables $act1 = "SUBSCRIBEa"; $act2 = "SUBSCRIBEb"; $act3 = "SUBSCRIBE"; $act4 = "SUBSCRIBE"; // set error false as default $error = false; // check if variables are ready for use, if they are, add them to `$acts` array // I do each check as a seperate line, as it looks cleaner than 1 long if statement. $acts = []; if(!empty($act1)) $acts[] = $act1; if(!empty($act2)) $acts[] = $act2; if(!empty($act3)) $acts[] = $act3; if(!empty($act4)) $acts[] = $act4; // declare a whitelist (outside of loop) of things that should not produce an error $whiteList = [ 'SUBSCRIBE', 'SUB & LIKE', 'LIKE & COMMENT', 'DISLIKE', 'COMMENT', 'LIKE', 'FOLLOW', ]; //create an empty array to hold errors $errors = []; // check the acts for lenght, numbers and special characters // add all of the acts to an array to loop over foreach($acts as $key => $value) { //1 line ternary is cleaner than if/else statetmnt $errorKey = $key < 9? "0{$key}" : $key; //each row by default has no error $hasError = 0; // check the lenght //use regex to check if a string only contains letters. // check if value from act is in the whitelist declared above, if its not, set `$error` to true and set `$error_*` (with key) to "true" as well. // make sure you use `||` (or) here, not `&&` (and), otherwise this statement will not work properly. If it's `||` only 1 thing has to be wrong, if it's `&&` then all of them have to be wrong. if(strlen($value) > 15 || preg_match('/[^A-Za-z &]/', $value) || !in_array($value, $whiteList)) { $error = true; //if error occurs, set `$hasError` to 1, to later insert errorKey into array. $hasError = 1; } // if($hasError) { //store error in array, to loop through later $errors[] = $errorKey; } } // deliver the error message //Check if $error has been set to true at any point if($error) { //loop through error array, echo error message if $errorNumber matches. //at this point we KNOW there was an error at some point, no need to use a switch really foreach($errors as $errorNumber) { echo "Something went wrong here $errorNumber :o"; } } ?> Template code:

@csrf.exempt

Dispatching the request:

request.get_json(force=True)

Flask processing request:


(Pdb) p request._cached_json
'Request' object has no attribute '_cached_json'

When 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); }}}); is commented out, save() { $.post("/save", JSON.stringify({'name': 'aaa'}), accept_reply, "json"); } has no attribute @app.route('/save', methods=("POST",)) #@csrf.exempt def save(): order_data = request.get_json(force=True) return jsonify({"status": "ok"}) : @csrf.exempt raises exception, while request simply returns None.

1 个答案:

答案 0 :(得分:1)

这里的问题是Flask需要一个“Content-Type”:“application / json”标题来识别你发布了一个JSON包,否则我相信它认为你正在发送urlencoded表单数据。

如果我希望将JSON数据发送到Flask,我发现我不能使用任何jQuery“方便”的AJAX方法。

试试这个:

$.ajax({
    type: "POST",
    url: "{{ url_for('.update_formulary_mb') }}",
    contentType: "application/json",
    data: JSON.stringify({id: state.config, update: records}),
    dataType: "json",
    success: function(response) {
        console.log(response);
    },
    error: function(err) {
        console.log(err);
    },
});

编辑9/1/2017

事实证明,如果所有XHR请求都使用jQuery的ajaxSetup()方法需要相同的参数,可以使用jQuery post()方法:

$.ajaxSetup({
    contentType: "application/json"
});

这会将常用参数传递给所有 ajax及其使用范围内的衍生方法......所以如果你在所有的XHR调用中遵循相同的模式,它会很好用页...