JQuery ajax - how to send JSON with GET method? - python

I'm trying to send some data from JQuery.ajax() to my python Flask server, JS code is:
let data = JSON.stringify({nickname: "AAA", password: "BBB"});
$.ajax({
async: true,
data: data,
dataType : "json",
contentType: "application/json",
method: "GET",
url: "/test_back",
success: function() {},
error: function() {}
});
Python code is:
#app.route("/test_back", methods=["GET", "POST"])
def test_back():
print(request)
data = request.get_json()
print(data)
return jsonify({})
And print(data) is writing None in console, so I can't read it as a dict.
When I change method: "GET" to method: "POST", it works just fine.
So: how do I send JSON from JQuery to Flask, using method GET, correctly?

First of all add conditional for flask methods get and post its good practices :D
if request.method == "POST":
if request.method == "GET":
also try return the data not the empty jsonfy
return data
not
return jsonify({})_

Related

Issue with sending data to python flask from AJAX

I am not able to retrieve data field of AJAX in python flask.
Its shows type error when I try to retrieve data. type and forwho are of array type. When I alert them in AJAX it works.
Here is my code,
// Ajax
$.ajax({
url: '/products',
data: JSON.stringify({'type':type,'forwho': forwho}),
contentType: "application/json; charset=utf-8",
type: 'POST',
success: function(response){
/*alert("success");*/
$("#content").html(response);
},
error: function(error){
/*alert("error");*/
console.log(error);
}
});
# app.py
#app.route('/products', methods =['POST', 'GET'])
def all_products():
if request.method == 'POST':
print("inside all products post")
type = json.loads(request.form.get('type'))
forwho = json.loads(request.form.getlist('forwho'))
print(type)
print(forwho)
when I print print(request.args.get('typearr')) in all_products() it returns None
type =request.json['type']
forwho = request.json['forwho']
Flask automatically parses JSON when having application/JSON in your request.
This solution finally worked for me.
ajax:
data: JSON.stringify({'typearr':type,'forwho':forwho})
``````````````````
app.py:
#import ast
``````````````
data = request.get_data()
data = ast.literal_eval(data.decode("UTF-8"))
typearr = data['typearr']
forwho = data['forwho']

Unable to parse json data from ajax in flask

I am trying to pass data from ajax to routes.py in flask through json. I have sometimes made it pop up a dialog box with the actual data, but I am unable to parse the data or have it appear on a webpage itself..(I eventually need to have this data manipulate sql db but for now I am just trying to be able to manipulate the data).
routes.py
#app.route("/post", methods=['GET', 'POST'])
def post():
data = request.get_json()
jsonify(data=data)
x = request.json['index']
return render_template('post.html', x=x)
request.json['index'] does not work and throws TypeError: 'NoneType'
if I return jsonify(data=data) instead of have it before the return, I can see the data in a dialog window when I go to localhost:5000/post
index.html
<script>
$(function() {
$( "#sortable" ).sortable({
update: function(event, ui) {
var postData = $(this).sortable('serialize');
}
});
});
function postSave() {$( "li" ).each(function( index ) {
console.log( index + ": " + $( this ).attr('id') );
$.ajax({
url: '/post',
data: JSON.stringify({ "index" : index, "id" : $( this ).attr('id') } ),
type: 'POST',
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (data) {
alert(JSON.stringify(data));
}
});
var url = "/post";
$(location).attr('href',url);
});
}
</script>
post.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<!-- simply be able to parse through the data and print it here for testing purposes -->
</body>
</html>
all help is greatly appreciated, I am pulling my hair out as we speak :)
Your post route has been configured to handle both GET and POST requests, but you don't distinguish between GET and POST requests. Since there is no distinction between the two type of requests if your browser sent off a GET request to your post route on your flask server there will be no JSON data in your request. A simple conditional like the following: if flask.request.method == 'POST': can be used to distinguish between the two types of requests. With that being said, maybe you could try out something like the following:
#app.route('/post', methods=['GET', 'POST'])
def post():
if request.method == "POST":
req_data = request.get_json()
x = req_data['index']
return render_template('post.html', x=x)
else: # GET request
# handle as you see fit probably want to render a page
# with inputs for a user to fill out
return render_template(<page_you_wish_to_render>)
If this doesn't work could you please print out req_data? So we can see what the request looks like as it might be invalid JSON.
Also, your ajax call looks a little off, maybe you could edit just the Ajax part to something like the following:
$.ajax({
type : 'POST',
url : "{{url_for('post')}}",
contentType: 'application/json;charset=UTF-8',
data : {'index':index}
});
Lastly, I would put a debugger statement right before you send off your ajax request to make sure the request is correct.
Hopefully that helps!

Flask request.get_json() returns string not json

using Flask 1.0.2 on Windows and Python 3.6 64bit
first i send data via jquery ajax call, which on JS side is valid json
var myData = '{ "id": "' +clickedID +'" }'
$.ajax({
type: "POST", // HTTP method POST or GET
contentType: 'application/json; charset=utf-8', //content type
url: $SCRIPT_ROOT + '/colors/delete', //Where to make Ajax calls
dataType:'json', // Data type, HTML, json etc.
processData: false,
data:JSON.stringify(myData),
});
in flask I catch the POST request and try to parse it:
if request.method == "POST":
print("got request method POST")
if request.is_json:
print("is json")
data_json = request.get_json(force=True)
data_req = request.data
print("{} is {}".format(data_req, type(data_req)))
print("{} is {}".format(data_json, type(data_json)))
data_json2 = json.loads(request.get_json(silent=True, force=True))
print("{} is {}".format(data_json2, type(data_json2)))
print (request.json.keys())
with the result:
got request: POST
is json
b'"{ \\"id\\": \\"1\\" }"' is <class 'bytes'>
{ "id": "1" } is <class 'str'>
{'id': '1'} is <class 'dict'>
print (request.json.keys())
AttributeError: 'str' object has no attribute 'keys'
JSON.stringify() takes a Javascript object and turns it into a JSON string. You're not passing it an object, you're passing it a string, which is then converted into JSON again.
Because the request data contains double-encoded JSON, the request.json attribute gives you back a string rather than a dictionary.
To fix, change:
var myData = '{ "id": "' +clickedID +'" }'
to:
var myData = { id: clickedID }
In overview, you serialise an object to JSON, which is in effect a string, POST it using the JSON data type, then deserialise it to get the object back. Some objects are easy to serialise and de-serialise with off the shelf functions). See an example based your code modified below (Ignore the CORS as that's due to my test evironment set up).
import logging, json
from flask import Flask, request, jsonify
from flask_cors import CORS
app = Flask(__name__)
CORS(app)
#app.route("/api",methods=['POST'])
def hello():
logging.info('hello')
if request.method == "POST":
print("got request method POST")
if request.is_json:
print("is json")
data = request.get_json()
print("type of data {}".format(type(data))) # type dict
print("data as string {}".format(json.dumps(data)))
print ("keys {}".format(json.dumps(data.keys())))
return jsonify(message='success')
if __name__ == "__main__":
app.run()
<html>
<style>
</style>
<button onClick="_ajax()">POST</button>
<script src="jquery.js"></script>
<script>
const url_path = "http://localhost:5000/api";
function _ajax() {
console.log('_ajax called');
var xhttp = new XMLHttpRequest();
var clickedID="testClickedID";
var myData = {"id": clickedID};
$.ajax({
type: "POST", // HTTP method POST or GET
contentType: 'application/json; charset=utf-8', //content type
url: url_path, //Where to make Ajax calls
dataType:'json', // Data type, HTML, json etc.
processData: false,
data: JSON.stringify(myData),
}).done(
function(data) {
console.log(data);
}
);
}
</script>
</html>

Flask receiving Post Json

I'm working on a flask web application in which the client posts data to the server in the form of:
{
"sess_id" : 1 ,
"annotations" :
[ {"tag_start" : "TIME","tag_end" : "TIME","tag" : "YOUR_TAG"}, {"tag_start" : "TIME","tag_end" : "TIME","tag" : "YOUR_TAG"}, {"tag_start" : "TIME","tag_end" : "TIME","tag" : "YOUR_TAG"}]
}
Here is the full Ajax post...
$.ajax({
url: 'http://127.0.0.1:5000/api/saveannotation',
type: 'POST',
headers: {'Content-Type' : 'application/json'},
data: {'sess_id' : $('#sessionid_area').val(),
'annotations': JSON.parse(annotations)},
success: function(data) { alert(data.status); }
});
so I can even see this on the api side, which is defined as such:
#sessionapis.route('/saveannotation', methods=['GET', 'POST'])
#login_required
def save_annotation():
rData = request.data
if request.method == 'GET':
return jsonify({'status' : 'success GET'})
else:
return jsonify({'status' : 'success'})
The issue is that data is a "byte" type, not a dict. I also can't call request.json or request.get_json(silent=True), it returns "400 bad request".
Here is a sample of what is in request.data:
b'sess_id=1&annotations%5B0%5D%5Btag_start%5D=2...
it appears to be url encoded for some reason. Values is also empty. If I choose to do something wild, like leave out the content-type = json; I can get a dict-like thing, but I have to access it very oddly. I don't get individual objects, but rather just flat access to all properties.
Any thoughts on how to just get the json parsed into a reasonable object?
Thanks for any hints!
Just passing a content-type header of JSON doesn't actually make the data itself into JSON. You either need to do that yourself, or tell jQuery to do so.
$.ajax({
url: 'http://127.0.0.1:5000/api/saveannotation',
type: 'POST',
contentType: 'application/json',
data: JSON.stringify({'sess_id' : $('#sessionid_area').val(),
'annotations': JSON.parse(annotations)}),
success: function(data) { alert(data.status); }
});
Now your data will be in JSON format and you can get it as a Python dict with request.get_json().

Passing data between client and Flask

I have a Flask application where I have a form that collects some user input. That input is then passed as JSON data via an AJAX call to a function in my Python script.
This function calls an API, gets some new data and then returns a redirect URL to the AJAX call. On success, AJAX then redirects to this new template with window.location.href.
I tried 'passing' the first view function, the_search, over to the second view function to then render the appropriate template but this didn't do the trick unfortunately. I've also tried setting the data as a session variable and then accessing it in the template but this doesn't seem to work either.
My issue
How can I access the variable 'response' within the redirected template, results.html?
AJAX script
...
$.ajax({
type: 'POST',
url: '/the_search',
data: JSON.stringify(data),
contentType: "application/json; charset=utf-8",
success: function(data, status) {
window.location.href = data['website'];
},
error: function() {
console.log('there was an error');
}
})
...
Python script
#app.route('/the_search', methods=("POST", 'GET'))
def the_search():
data = json.loads(request.data)
lat = data['latitude']
longitude = data['longitude']
response = unirest.get("https://zilyo.p.mashape.com/search?latitude={}&longitude={}".format(lat, longitude),
headers={
"X-Mashape-Key": "k6HBYxvy88mshQ6Yg1xPVuv7Vg9Np1GZj7IjsnPxploykdpaHA",
"Accept": "application/json"})
session['search_results'] = response.body
return jsonify({'website': '/results'}), 200
#app.route('/results', methods=('POST', 'GET'))
def results():
#How can I pass the_search view function to here while still having access to the response data
print session['search_results']
return render_template('results.html')

Categories