Flask not getting any data from jQuery request data
interesting, as it turns out you can only use request.data
if the data was posted with a mimetype that flask can't handle, otherwise its an empty string ""
I think, the docs weren't very clear, I did some tests and that seems to be the case, you can take a look at the console output the flask generates when you run my tests.
Incoming Request Data
data
Contains the incoming request data as string in case it came with a mimetype Flask does not handle.
taken from http://flask.pocoo.org/docs/api/
but since we are doing a standard POST
using json flask
can handle this quite well as such you can access the data from the standard request.form
this ss=str(request.form)
should do the trick as I've tested it.
As a side note @crossdomain(origin='*')
this seems dangerous, theres a reason why we don't allow cross site ajax requests, though Im sure you have your reasons.
this is the complete code I used for testing:
from flask import Flaskapp = Flask(__name__)from datetime import timedeltafrom flask import make_response, request, current_appfrom functools import update_wrapperdef crossdomain(origin=None, methods=None, headers=None, max_age=21600, attach_to_all=True, automatic_options=True): if methods is not None: methods = ', '.join(sorted(x.upper() for x in methods)) if headers is not None and not isinstance(headers, basestring): headers = ', '.join(x.upper() for x in headers) if not isinstance(origin, basestring): origin = ', '.join(origin) if isinstance(max_age, timedelta): max_age = max_age.total_seconds() def get_methods(): if methods is not None: return methods options_resp = current_app.make_default_options_response() return options_resp.headers['allow'] def decorator(f): def wrapped_function(*args, **kwargs): if automatic_options and request.method == 'OPTIONS': resp = current_app.make_default_options_response() else: resp = make_response(f(*args, **kwargs)) if not attach_to_all and request.method != 'OPTIONS': return resp h = resp.headers h['Access-Control-Allow-Origin'] = origin h['Access-Control-Allow-Methods'] = get_methods() h['Access-Control-Max-Age'] = str(max_age) if headers is not None: h['Access-Control-Allow-Headers'] = headers return resp f.provide_automatic_options = False return update_wrapper(wrapped_function, f) return decorator@app.route("/", methods=['POST'])@crossdomain(origin='*')def hello(): ss=str(request.form) print 'ss: ' + ss + ' request.data: ' + str(request.data) return ss@app.route("/test/")def t(): return """<html><head></head><body><script src="http://code.jquery.com/jquery.min.js" type="text/javascript"></script><script type='text/javascript'>jQuery.ajax( { type: "POST", dataType: "json", data: "adasdasd", url: 'http://127.0.0.1:5000/',complete: function(xhr, statusText) { alert(xhr.responseText) }})var oReq = new XMLHttpRequest();oReq.open("POST", "/", false);oReq.setRequestHeader("Content-Type", "unknown");oReq.send('sync call');alert(oReq.responseXML);</script></body></html>"""if __name__ == '__main__': app.run()
output:
$ python test.py * Running on http://127.0.0.1:5000/127.0.0.1 - - [07/Aug/2012 02:45:28] "GET /test/ HTTP/1.1" 200 -ss: ImmutableMultiDict([('adasdasd', u'')]) request.data: 127.0.0.1 - - [07/Aug/2012 02:45:28] "POST / HTTP/1.1" 200 -ss: ImmutableMultiDict([]) request.data: sync call127.0.0.1 - - [07/Aug/2012 02:45:28] "POST / HTTP/1.1" 200 -127.0.0.1 - - [07/Aug/2012 02:45:29] "GET /favicon.ico HTTP/1.1" 404 -
and my system:
$ python --versionPython 2.6.1$ python -c 'import flask; print flask.__version__;'0.8$ uname -aDarwin 10.8.0 Darwin Kernel Version 10.8.0: Tue Jun 7 16:33:36 PDT 2011; root:xnu-1504.15.3~1/RELEASE_I386 i386
using google chrome Version 20.0.1132.57
I have been working with similar functionality and after a bit of messing around with the ajax and python, this is what I came up with for python reading the ajax data
JavaScript:
var data = { data: JSON.stringify({ "value":'asdf' }) }};$.ajax({ url:"/", type: 'POST', data: data, success: function(msg){ alert(msg); }})
Python:
from flask import json@app.route("/", methods=['POST'])def get_data(): data = json.loads(request.form.get('data')) ss = data['value'] return str(ss)
This worked for me.
In Javascript:
$.ajax({ type: 'POST', url: "enter your correct url", contentType: "application/json; charset=utf-8", data: JSON.stringify({title: 'My Title', article: 'My article'}), success: function(result){ console.log(result) }});
In Python (flask):
from flask import request import json @app.route("/", methods=['POST']) def home(): json_data = json.loads(request.data) print(json_data) return json_data
NOTE: The points are;
- JSON.stringify()
- contentType: "application/json; charset=utf-8"
- json.loads
- request.data