Ok!! I'm building a flask web app, and I want to use Ajax to send some json data Here is my code!! for the HTML and js :
<!DOCTYPE html>
<html >
<head>
<meta charset="UTF-8">
<title>Check your Grades</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script src="{{ url_for('static', filename='js/bootstrap3-typeahead.min.js')}}"></script>
<script type="text/javascript" src="{{ url_for('static', filename='js/index.js')}}"></script>
<link rel="stylesheet" href="{{url_for('static', filename='css/style.css')}}">
</head>
<body>
<link href='https://fonts.googleapis.com/css?family=Lato' rel='stylesheet' type='text/css'>
<form id="predict-form" method="POST">
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>
<p> welcome to grade predictor app,</p>
<p>Dear Plateform,</p>
<p>je viens
<label for="SCHOOL_RIGHT"> de </label>
<input class="typeahead" type="text" name="SCHOOL_RIGHT" id="SCHOOL_RIGHT" minlength="3" placeholder="(votre ecole de provenance)" data-provide="typeahead" autocomplete="off" required> et </p>
<p>dans
<label for="OPTION_RIGHT">l'option</label>
<input class="typeahead"
name="OPTION_RIGHT" id="OPTION_RIGHT" data-provide="typeahead" placeholder="(choisissez votre option )" required>
</p>
<p>j'ai obtenu
<label for="DIPPERC"></label>
<input type="number" name="DIPPERC" min="50" max="100" id="DIPPERC" placeholder="(Poucentage du
diplome )" required> % à l\'exetat
</p>
<p>
<button type="submit">
<svg version="1.1" class="send-icn" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="100px" height="36px" viewBox="0 0 100 36" enable-background="new 0 0 100 36" xml:space="preserve">
<path d="M100,0L100,0 M23.8,7.1L100,0L40.9,36l-4.7-7.5L22,34.8l-4-11L0,30.5L16.4,8.7l5.4,15L23,7L23.8,7.1z M16.8,20.4l-1.5-4.3
l-5.1,6.7L16.8,20.4z M34.4,25.4l-8.1-13.1L25,29.6L34.4,25.4z M35.2,13.2l8.1,13.1L70,9.9L35.2,13.2z" />
</svg>
<small>send</small>
</button>
</p>
</form>
<script >
var csrf_token = "{{ csrf_token() }}";
// this will send a token each time before a session started
$.ajaxSetup({
beforeSend: function(xhr, settings) {
if (!/^(GET|HEAD|OPTIONS|TRACE)$/i.test(settings.type) && !this.crossDomain) {
xhr.setRequestHeader("X-CSRFToken", csrf_token);
}
}
});
//submit form data
$("form#predict-form").submit(function(e){
console.log("form submitted")
e.preventDefault();
var data = {
}
var Form = this;
//Gathering the Data
//and removing undefined keys(buttons)
$.each(this.elements, function(i, v){
var input = $(v);
data[input.attr("name")] = input.val();
delete data["csrf_token"];
delete data["undefined"];
});
data["DIPPERC"] = data["DIPPERC"]/100.0
//Form Validation goes here....
//Save Form Data........
$.ajax({
cache: false,
url : "{{url_for('predict')}}",
type: "POST",
contentType: "application/json; charset=utf-8",
dataType: "json",
data : JSON.stringify(data),
success : function(callback){
//Where $(this) => context == FORM
console.log("data sucessfuly submitted")
console.log(JSON.parse(callback));
}
,
error : function(){
console.log('erroor')
}
});
})
</script>
</body>
</html>
I've tried everything possible but still getting the 400 error! I've checked all related questions but nothing.
But my research shows that the 400 error can be caused by this according to :
- from here it's said that :
The HTTP 400 Bad Request response status code indicates that the server could not understand the request due to invalid syntax. The client should not repeat this request without modification.
- Csrf token missing this I've already added the token , and try to send the data to the route with csrf.exempt but nothing
- ContentType and applicationType not set (already do it but nothing)
- Already check in the official flask documentation they say : (from )
- I'm sending correct json data
- So what may cause this problem ??? here is my simple view function
@predictions.route('/predictions/predict/', methods=['GET', 'POST'])
def predict():
if request.method == 'POST':
print "hello----------------------"
print request.method
print request.get_json(force=True)
return "done "
Note in my test when I send directly data via python to my route it works with this code :
def test_1_can_connect_post(self):
"""
Test API can create a (POST request)
"""
new_student = {
'DIPPERC':0.60, 'SCHOOL_RIGHT':'itfm/bukavu', 'OPTION_RIGHT':'elec indust'
}
res = self.client().post('predictions/predict/', data=json.dumps(new_student), content_type='application/json')
self.assertEqual(res.status_code, 201)
Ps: I'm sure that I'm missing a little thing but don't know what, maybe something wrong with ajax asynchronous .....
Ok , after 7 days of debugging i just found a solution for my problem : i do two things:
from now and for my future web development i will stop using jquery and I'm sure that soon i will found good reason for that , so for my code i decide to use plain javascript and here is the code i use to send the request :
this was for the javascript part and I was sure that i was sending good json object to my server
i went here at flask official documentation and found these 2 lines of attributes of flask request object
and
and change my backend code to this :
And VOILA!!!! get the 200 status code and the data as a python dict.