Reputation: 3721
Using ajax
I'm trying to send data to my Tornado server, this is my JQuery:
$("#addTask").submit(function(e){
e.preventDefault();
var add = $('#addProject').val();
var added={projectAdded:add};
$.post("/task",
JSON.stringify(added),
function(data){
window.location.reload(true);
});
});
The value of $('#addProject').val();
is from an input text field:
$('<div class="input-group col-sm-7"><input type="text" form="task" class="form-control" id="addProject" name="projectAdd" value="" placeholder="New tag">
<button type="submit" name="addTag" value="addTag" form="task" id="addTask"></button> </div>').appendTo('#proj');
In my Tornado server I have:
class TaskAddHandler(BaseHandler):
def post(self):
addProj = json.loads(self.request.body)
print 'NEW TASK', addProj
But this gives me the error: raise ValueError("No JSON object could be decoded")
ValueError: No JSON object could be decoded
, instead of the value of the input text field.
Upvotes: 1
Views: 2405
Reputation: 3661
The data is in self.request.arguments
. Also, you need to return valid json to the client.
class AjaxHandler(tornado.web.RequestHandler):
def post(self):
my_data = self.request.arguments['test_data']
# do something with my_data
self.write(json.dumps({'status': 'ok'}))
self.finish()
The self.write(json.dumps({'status': 'ok'}))
response from the handler is necessary to complete the transaction with the client: any valid json will do; it doesn't matter what the content is. (See this answer if the client does not seem to get the json back.)
It could also be that _xsrf_cookies: True
in your settings
within run_server.py
. If that's the case, the ajax
request itself will be blocked by Tornado (and you'll see 400 Bad Request
on the console).
To deal with that, "the XSRF
token may... be passed via an HTTP
header named X-XSRFToken
," says the doc. Set the cookie via the get
of whatever page contains, or calls, that ajax
logic, via self.xsrf_token
. Doing so, the doc says, "is enough to set the cookie as a side effect":
class PageHandler(tornado.web.RequestHandler):
def get(self):
self.xsrf_token
self.render('page.html')
Can then pick up the cookie in the client (here via the jQuery $.cookie plugin):
var token = $.cookie('_xsrf');
Embed the token as a custom headers
parameter in the call:
$.ajax({
url: '/task',
headers: {'X-XSRFToken' : token },
data: {'test_string': 'test success'},
dataType: "JSON",
type: "POST",
success: function ( data , status_text, jqXHR) {
alert('ajax success')
},
error: function ( data , status_text, jqXHR ) {
alert('ajax fail')
},
});
Alternately, you can also put it as one of the fields in data
. (And if you are ajax
ing a JavaScript object as one of your fields, you should JSON.stringify
it in order to get a nicely-structured dict
back on the server side):
var packet = {"_xsrf": $.cookie("_xsrf"), "test_string": "test success", "js_obj": JSON.stringify(js_obj)};
$.ajax({
url: '/task',
data: packet,
dataType: "JSON",
type: "POST",
success: function ( data , status_text, jqXHR) {
alert('ajax success')
},
error: function ( data , status_text, jqXHR ) {
alert('ajax fail')
},
});
There is also an example of managing _xsrf_cookies
in the sample chat app referred to in the doc.
Upvotes: 4
Reputation: 2109
I think you need to send a JSON string as your data, not the object. Try JSON.stringify({projectAdded:add}) instead of just the object.
Upvotes: 0