web2py - getting posted json data through jquery - python

I'm new to web2py, trying to alter an existing application.
I have a JSON object in my JS, which I want to send to the server.
My JS is:
post_data = {ios: [{k:"v"},
{k: "v"},
{k: "v"}]};
$.post("/url", post_data, function(data) {}, "json"); // used with 'json' and without, same results
I want to access this data in my controller. so there, I tried to use request.vars.ios and request.post_vars.ios, getting a None ...
What am I doing wrong?
(note: the data is transmitted, and if i try to dump the request.vars, I get something like
<Storage {'ios[1][ranges_colors]': '', 'ios[0] .... etc which contains the data)

Try this, on the client:
$.ajax({
type: 'POST',
url: '/url.json',
contentType: "application/json; charset=utf-8",
data: post_data,
dataType: 'json',
success: function(data) { alert('Data sent'); }
});
Then on the server:
data = gluon.contrib.simplejson.loads(request.body.read())

Related

django get data from api with ajax

I was trying to get some information from API using ajax. I was able to post data but I was unable to get all the data from the server. I am new in the Django environment, though i have tried some references. I was wanted to get the data from the server using the API that I provide and show those data by using ajax get call.
References that I have followed:
1.Django Ajax Jquery Call
2.https://simpleisbetterthancomplex.com/tutorial/2016/11/15/how-to-implement-a-crud-using-ajax-and-json.html
3.https://www.sourcecodester.com/tutorials/python/11762/python-django-simple-crud-ajax.html
My code for get call:
$.ajax({
type: "GET",
url: "/save_composition",
dataType: "json",
success: function(data) {
alert(data)
},
error: function(xhr, textStatus) {
alert("error..");
}});
Url section :
path('restore_composition/', views.restore_composition, name='restore_composition')
Views.py:
def restore_composition(request):
data = SaveComposition.objects.all()
return render(request, 'index.html', context={'data': data})
This is how ajax calls works in Django framework.
def ajax_method():
return HttpResponse(200)
url to the ajax call
path('save_composition', views.ajax_method, name='ajax_method')
You need to set the `url-path' without forward-slash
Ajax call
$.ajax({
type: "GET",
url: "save_composition",
dataType: "json",
success: function(data) {
alert(data)
},
error: function(xhr, textStatus) {
alert("error..");
}});

Sending JSON to Flask with jQuery gives error [duplicate]

This question already has answers here:
jQuery posting JSON
(3 answers)
Closed 6 years ago.
I want to use jQuery to send JSON data to a Flask route. However, request.get_json() gives an error. Why doesn't this work?
my_array = {"student_data":{"actual_data":12,"sheet_data":23,"age":"20"},"teacher_data":{"actual_data":193,"sheet_data":203,"age":"40"},"school_data":{"actual_data":593,"sheet_data":29,"age":"49"}};
$.ajax({
url: '/submit_method',
data: my_array,
contentType: 'application/json; charset=utf-8',
type : 'GET',
async: 'false',
success: function (serverResponse) {
}
});
#app.route('/submit_method', methods=['GET'])
def submit_method():
k = request.get_json()
return ''
You have to use POST method instead of GET.
#app.route('/submit_method', methods=['POST'])
def submit_method():
k = request.data # gets request body in form of dictionary
return json.dumps(k) # converts dictionary to json
$.ajax({
url: '/submit_method', data: JSON.stringify(my_array),
contentType:"application/json; charset=utf-8",
type : 'POST', async: "false", success : function (serverResponse) {}});
The issue is JavaScript has to be converted to a JSON string first, using JSON.stringify. Otherwise Flask will not consider it application/json content type and deny the request with a 400.
$.ajax({
url: '/submit_method',
data: JSON.stringify(my_array),
contentType: 'application/json; charset=utf-8',
type : 'GET',
async: 'false',
success: function (serverResponse) {
}
});

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().

How to post data structure like json to flask?

I have a data structure like this:
I'm try to send it to server by $.ajax:
$.ajax({
type: 'POST',
data: post_obj, //this is my json data
dataType: 'json',
url: '',
success: function(e){
console.log(e);
}
});
and I want get it in server by flask: title = request.form['title'] working fine!
But how do I get content ?
request.form.getlist('content') doesn't work.
This is the post data in firebug:
Thanks a lot :D
You are sending your data encoded as query string instead of JSON. Flask is capable of processing JSON encoded data, so it makes more sense to send it like that. Here's what you need to do on the client side:
$.ajax({
type: 'POST',
// Provide correct Content-Type, so that Flask will know how to process it.
contentType: 'application/json',
// Encode your data as JSON.
data: JSON.stringify(post_obj),
// This is the type of data you're expecting back from the server.
dataType: 'json',
url: '/some/url',
success: function (e) {
console.log(e);
}
});
On the server side data is accessed via request.json (already decoded):
content = request.json['content']
If you inspect the POST being submitted by jQuery, you will most likely see that content is actually being passed as content[]. To access it from the Flask's request object, you would then need to use request.form.getlist('content[]').
If you would prefer to have it passed through as content, you can add traditional: true to your $.ajax() call.
More details about this can be found in the 'data' and 'traditional' sections of http://api.jquery.com/jQuery.ajax/.

Decoding JSON with python using Appengine

I have the following code which retrieves values from a simple 3 input form:
//retrieves data from a form
var $form = $( this ),
prgname= $form.find('input[name="prg"]').val(),
startDate = $("#startdate").datepicker({ dateFormat: 'yy-mm-dd' }).val(),
endDate = $("#enddate").datepicker({ dateFormat: 'yy-mm-dd' }).val();
The following code sends the request to the server:
var request = $.ajax({
url: "/prg/",
type: "post",
data: JSON.stringify({prg: prgname, start:startDate, end:endDate}),
contentType: 'application/json',
dataType: 'json',
success: function() {},
error: function (jqXHR, textStatus, errorThrown){};
on the server end using python and webapp2 Im doing the following, (here is where I am unsure of things)
import json
class PrgHandler(webapp2.RequestHandler):
def post(self):
prg= cgi.escape(self.request.POST['prg'])
start_date = cgi.escape(self.request.POST['start'])
end_date = cgi.escape(self.request.POST['end'])
#some code to write to db here
....
#if successful return a success message
if success:
success_msg = [{'class': 'success', 'msg': 'Successfully saved to the database'}]
else:
success_msg = [{'class': 'error', 'msg': 'Could not saved to the database'}]
data_string = json.dumps(success_msg)
self.response.headers.add_header('content-type', 'application/json', charset='utf-8')
self.response.write(data_string)
When I get the response it is skipping the success function and going directly to the error.
Logging the error values im not getting any thing meaningful:
the error is:
The text status is:error
The jqXHR is:[object Object]
Chrome's console is giving me the error:
Resource interpreted as Document but transferred with MIME type application/json:
I looked that up and the solutions on SO did not work, I think this is an error with the server side code:
self.response.headers.add_header('content-type', 'application/json', charset='utf-8')
If I comment out the above line I get no error in chrome and I just get back the response on a blank page with the correct values in the following format:
[{"msg": "Successfully saved to the database", "class": "success"}]
In the above case it does save to the database so I cannot seem to find anything wrong except for the header and simply don't know how to proceed!
EDIT
The error it seems is from the server side I had removed the following line:
event.preventDefault();
from my script and it caused all the problems now at least Im getting a clear indication of where the problem is. It's from incorrectly getting the posted data, how would I do it the correct way? I tried the following:
json_data = self.request.GET.items()
decoded = json.loads(json_data)
but Im getting a TypeError: expected string or buffer on the following line:
json_data = self.request.GET.items()
Have a look in your debugger. You receive a JSON string in your post (webapp2 multidict). You have to decode this string using json.loads, resulting in a python object.
Here is my jquery code to send and receive json :
function gaeQuery(request) {
var url = "/query";
var payload = {'jsondata' : JSON.stringify(request)};
$.post(
url,
payload,
function(response) {
procesResponse(response);
}, // succes response callback
'json', // response contains JSON content, and will be decoded in a js object
{
contentType: "application/json;charset=utf-8", // send JSON content
timeout: 20000,
tryCount: 0,
retryLimit: 3, // max 3 retries
error: function(xhr, textStatus, errorThrown) { // error handling callback
if (textStatus === 'timeout') {
this.tryCount++;
if (this.tryCount <= this.retryLimit) { //try again until retryLimit
$.ajax(this);
return;
}
alert('We have tried ' + this.retryLimit + ' times and it is still not working. We give in. Sorry.');
return;
}
if (xhr.status === 500) { // internal server error
alert('Oops! There seems to be a server problem, please try again later.');
}
else {
alert('Oops! There was a problem, sorry.'); // something went wrong
}
}
}
);
}
OK so I managed to figure this out and thought I will post the answer that worked for me to help anyone looking for this information because the webapp2 docs are not that helpful when it comes to 'getting' posted json data.
on the client side I did the following:
var request = $.ajax({
url: "/some/url/",
type: "POST",
data: JSON.stringify([{someval: val1, someval2:val2, someval3:val3}]),
contentType: "application/json",
dataType: 'json',
beforeSend: function() {
$('#loading-div').show();
},
complete: function(){
$('#loading-div').hide();
},
success: function(response, textStatus, jqXHR){}
});
The reason I couldnt figure out the problem straight away was because of the following line which I deleted along with some commented out line which prevented the page from redirecting after posting. This was the source of all the weird, unrelated and unhelpful error messages:
event.preventDefault();
on the server side to get the json data being posted to appengine do the following:
jdata = json.loads(cgi.escape(self.request.body))
for vals in jdata:
val1 = vals['someval']
val2 = vals['someval2']
val3 = vals['someval3']
The above was the root of the problem I wasn't doing it right and without the previous line on the client side there was no way to figure it out.
Anyways once you have the data do whatever processing you need to do with it and once you are done and need to send back a json response add the following lines:
//the data would look something like this
data = {'return_value': val1, 'return_value2': val2,
'return_value3': val3, 'return_value4': val4}
return_data = json.dumps(data)
self.response.headers.add_header('content-type', 'application/json', charset='utf-8')
self.response.write(return_data)
Almost forgot on the client side again to access the variables sent back from the server with jquery its very straight forward...do something like:
success: function(response, textStatus, jqXHR){
console.log(response.return_value);
console.log(response.return_value2);
console.log(response.return_value3);
}
Hope this will help someone seeking this information.

Categories