0

I'm trying to parse a POST request made through AJAX using jQuery in a python script. The request is constructed as bellow:

request.js

function get_form_data($form){
    var unindexed_array = $form.serializeArray();
    var indexed_array = {};

    $.map(unindexed_array, function(n, i){
         indexed_array[n['name']] = n['value'];
    });

    return indexed_array;
}

uri = location.protocol + '//' + location.host + "/sign_up";
method = "POST";
formId = "#signup_form_id";

$form = $(formId);
form_data = get_form_data($form);

// Set-up ajax call
var request = {
    url: uri,
    type: method,
    contentType: "application/json",
    accepts: "application/json",
    cache: false,
    dataType: "json",
    data: JSON.stringify(form_data)
};
// Make the request
$.ajax(request).done(function(data) { // Handle the response
    // Attributes are retrieved as object.attribute_name
    // alert(obj.count);
    console.log("Data from sign up from server: " + data);
    jsonObject = JSON.parse(data);
    if(jsonObject.successSignUp === false) {
        // Signup failed we show the welcome page
        alert("Sign-up failed!");
    } else {
        alert("Sign-up complete!");
    }
    // Show the welcome page regardless whether the sign up failed or not
    document.getElementById("main").innerHTML = document.getElementById("welcomeview").innerHTML;
}).fail(function(jqXHR, textStatus, errorThrown) { // Handle failure
            console.log(JSON.stringify(jqXHR));
            console.log("AJAX error on sign up: " + textStatus + ' : ' + errorThrown);
        }
);

Watching the request call in firebug suggests that the request is being sent correctly(a JSON object is sent to the expected URL with the appropriate headers and body):

headers:

headers

request:

request

On the server side the JSON is retrieved:

serverside.py

@app.route('/sign_up', methods=['POST'])
def sign_up_helper():
    # The received JSON object is parsed
    # data = request.get_json(force=True)  I've tried all variations. Same result
    # data = json.loads(data)
    data = request.json
    data = json.loads(data)

    with open('data.txt', 'w') as outfile: # Strangely a file is not even created in web root directory
        json.dump(data, outfile)

    # We explicitly retrieve the object's attribute values
    s_fname = data['s_fname']
    s_lname = data['s_lname']
    s_city = data['s_city']
    s_country = data['s_country']
    sex = data['sex']
    s_email = data['s_email']
    s_password = data['s_password']

    json_obj = sign_up(s_fname, s_lname, s_city, s_country, sex, s_email, s_password)

    resp = Response(response=json_obj,
                    status=200, \
                    mimetype="application/json")
    return(resp)


def sign_up(s_fname, s_lname, s_city, s_country, sex, s_email, s_password):
    """
    check if the email exists in the database. We (insecurely) rely on client side validation for the input fields.
    """
    data = query_db('SELECT * FROM Users WHERE email = ?', [s_email], one=True)
    if data is not None:
        return jsonify(
            successSignUp=False,
            message="Email already exists"), 400

    insert_db('INSERT INTO Users  (email, firstname, lastname, gender, city, country, password) \
        VALUES (?, ?, ?, ?, ?, ?, ?)',
              [s_email, s_fname, s_lname, sex, s_city,
               s_country, generate_password_hash(s_password)])
    return jsonify(
        successSignUp=True,
        message="Account created successfully")

The following exception:

TypeError: expected string or buffer

is generated, when presumably, an element of the JSON object is being accessed. The whole stack trace is as follows:

Traceback (most recent call last):
  File "C:\Python27\lib\site-packages\flask\app.py", line 1836, in __call__
    return self.wsgi_app(environ, start_response)
  File "C:\Python27\lib\site-packages\flask\app.py", line 1820, in wsgi_app
    response = self.make_response(self.handle_exception(e))
  File "C:\Python27\lib\site-packages\flask\app.py", line 1403, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "C:\Python27\lib\site-packages\flask\app.py", line 1817, in wsgi_app
    response = self.full_dispatch_request()
  File "C:\Python27\lib\site-packages\flask\app.py", line 1477, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "C:\Python27\lib\site-packages\flask\app.py", line 1381, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "C:\Python27\lib\site-packages\flask\app.py", line 1475, in full_dispatch_request
    rv = self.dispatch_request()
  File "C:\Python27\lib\site-packages\flask\app.py", line 1461, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "C:\Users\mg13\Desktop\School\WebPython\twidder\twidder\app\server.py", line 126, in sign_up_helper
    data = json.loads(data)
  File "C:\Python27\lib\json\__init__.py", line 338, in loads
    return _default_decoder.decode(s)
  File "C:\Python27\lib\json\decoder.py", line 366, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
TypeError: expected string or buffer

I don't understand why there isn't a JSON object with the same attributes and values as seen in the request created/received on the server side.

1 Answer 1

2

Correct way to access key of json is:

s_fname = data.get('s_fname','')

It will handle exception if you don't have key in request body.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.