1

I am having problems parsing a serialized JSON Ajax Get request (using jQuery $.ajax) send to my express.js 4 server. The data send as a JSON request is generated by datatables.

Here is how I started on the client-side

$(document).ready(function() {
    $('#example').dataTable( {
        "bServerSide": true,
        "fnServerData": function (sSource, aoData, fnCallback) {
            $.ajax({
                "dataType": 'json',
                contentType: 'application/json',
                "type": "GET",
                "url": "http://localhost:3000/ajax/phenotypes/withOrg/like/datatables/",
                "data": aoData,
                "success": fnCallback,
                "error": function () {
                    alert('have some problem');
                }
            });
        }                   
    } );
} );

when I load this code in the brower datatables generates the following GET request URL (to the server):

GET /ajax/phenotypes/withOrg/like/datatables/?draw=1&columns=%5Bobject+Object%5D%2C%5Bobject+Object%5D%2C%5Bobject+Object%5D%2C%5Bobject+Object%5D%2C%5Bobject+Object%5D%2C%5Bobject+Object%5D&order=%5Bobject+Object%5D&start=0&length=10&search=%5Bobject+Object%5D

or in decoded form (output from firebug)

 columns    [object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
    draw    1
    length  10
    order   [object Object]
    search  [object Object]
    start   0

so I serialized the data before sending

$(document).ready(function() {
            $('#example').dataTable( {
                "bServerSide": true,
                "fnServerData": function (sSource, aoData, fnCallback) {
                    var myData = JSON.stringify(aoData);
                    $.ajax({
                        "dataType": 'json',
                        contentType: 'application/json',
                        "type": "GET",
                        "url": "http://localhost:3000/ajax/phenotypes/withOrg/like/datatables/",
                        "data": myData,
                        "success": fnCallback,
                        "error": function () {
                            alert('have some problem');
                        }
                    });
                }                   
            } );
        } );

here is the generated GET parameters from datatables:

GET /ajax/phenotypes/withOrg/like/datatables/?[{%22name%22:%22draw%22,%22value%22:1},{%22name%22:%22columns%22,%22value%22:[{%22data%22:0,%22name%22:%22%22,%22searchable%22:true,%22orderable%22:true,%22search%22:{%22value%22:%22%22,%22regex%22:false}},{%22data%22:1,%22name%22:%22%22,%22searchable%22:true,%22orderable%22:true,%22search%22:{%22value%22:%22%22,%22regex%22:false}},{%22data%22:2,%22name%22:%22%22,%22searchable%22:true,%22orderable%22:true,%22search%22:{%22value%22:%22%22,%22regex%22:false}},{%22data%22:3,%22name%22:%22%22,%22searchable%22:true,%22orderable%22:true,%22search%22:{%22value%22:%22%22,%22regex%22:false}},{%22data%22:4,%22name%22:%22%22,%22searchable%22:true,%22orderable%22:true,%22search%22:{%22value%22:%22%22,%22regex%22:false}},{%22data%22:5,%22name%22:%22%22,%22searchable%22:true,%22orderable%22:true,%22search%22:{%22value%22:%22%22,%22regex%22:false}}]},{%22name%22:%22order%22,%22value%22:[{%22column%22:0,%22dir%22:%22asc%22}]},{%22name%22:%22start%22,%22value%22:0},{%22name%22:%22length%22,%22value%22:10},{%22name%22:%22search%22,%22value%22:{%22value%22:%22%22,%22regex%22:false}}] HTTP/1.1

in decoded form (output from firebug and beautified using an online tool- checked with jslint, seems correct!)

[
   {
      "name":"draw",
      "value":1
   },
   {
      "name":"columns",
      "value":[
         {
            "data":0,
            "name":"",
            "searchable":true,
            "orderable":true,
            "search":{
               "value":"",
               "regex":false
            }
         },
         {
            "data":1,
            "name":"",
            "searchable":true,
            "orderable":true,
            "search":{
               "value":"",
               "regex":false
            }
         },
         {
            "data":2,
            "name":"",
            "searchable":true,
            "orderable":true,
            "search":{
               "value":"",
               "regex":false
            }
         },
         {
            "data":3,
            "name":"",
            "searchable":true,
            "orderable":true,
            "search":{
               "value":"",
               "regex":false
            }
         },
         {
            "data":4,
            "name":"",
            "searchable":true,
            "orderable":true,
            "search":{
               "value":"",
               "regex":false
            }
         },
         {
            "data":5,
            "name":"",
            "searchable":true,
            "orderable":true,
            "search":{
               "value":"",
               "regex":false
            }
         }
      ]
   },
   {
      "name":"order",
      "value":[
         {
            "column":0,
            "dir":"asc"
         }
      ]
   },
   {
      "name":"start",
      "value":0
   },
   {
      "name":"length",
      "value":10
   },
   {
      "name":"search",
      "value":{
         "value":"",
         "regex":false
      }
   }
]

the problem is now that this stringified URL can not be parsed on the express 4 server side I use express4 req.query and url.parse method for this : http://expressjs.com/api.html#req.query and then try to parse the received json string with the JSON.parse() method

...
var url = require('url');
...

 router.get('/withOrg/like/datatables/', function (req, res) {
    console.log('getting json string via req.query');
    console.log(req.query);
    console.log('output parsed json object using JSON.parse');
    console.log(JSON.parse(req.query));

    //another try
    console.log('for stack overflows test 2');
    console.log(url.parse(req.url, true).query);
    console.log('output parsed json object using JSON.parse');
    console.log(url.parse(req.url, true).query);
})

both json string output results are invalid json as you can see here and unable to parse with JSON.parse:

getting json string via req.query

{ '{"data":0,"name":"","searchable":true,"orderable":true,"search":{"value":"","regex":false}},{"data":1,"name":"","searchable":true,"orderable":true,"search":{"value":"","regex":false}},{"data":2,"name":"","searchable":true,"orderable":true,"search":{"value":"","regex":false}},{"data":3,"name":"","searchable":true,"orderable":true,"search":{"value":"","regex":false}},{"data":4,"name":"","searchable":true,"orderable":true,"search":{"value":"","regex":false}},{"data":5,"name":"","searchable":true,"orderable":true,"search":{"value":"","regex":false}}': { '{"column":0,"dir":"asc"}': '' } }

output parsed json object using JSON.parse

getting json string via req.query

{ '{"data":0,"name":"","searchable":true,"orderable":true,"search":{"value":"","regex":false}},{"data":1,"name":"","searchable":true,"orderable":true,"search":{"value":"","regex":false}},{"data":2,"name":"","searchable":true,"orderable":true,"search":{"value":"","regex":false}},{"data":3,"name":"","searchable":true,"orderable":true,"search":{"value":"","regex":false}},{"data":4,"name":"","searchable":true,"orderable":true,"search":{"value":"","regex":false}},{"data":5,"name":"","searchable":true,"orderable":true,"search":{"value":"","regex":false}}': { '{"column":0,"dir":"asc"}': '' } }

output parsed json object using JSON.parse

when I try to parse the json string I get the error from JSON.parse

SyntaxError: Unexpected token o
    at Object.parse (native)
    at module.exports (/Users/xxx/yyy/routes/phenotypesAJAX.js:16:19)
    at Layer.handle [as handle_request] (/Users/xxx/yyy/node_modules/express/lib/router/layer.js:82:5)
    at next (/Users/xxx/yyy/node_modules/express/lib/router/route.js:100:13)

Is this a bug in express 4? I cannot see where the problem is. On the client-side the serialized datatable GET request seems valid (checked with JSLint). On the express4 server side I cannot find any other way to parse the GET request in a different way.

Thank you so much for your help, Oliver

1 Answer 1

0

I have got the answer from posting this problem at the express github bugtracker. Lesson learned: I was thinking to complicated, express.js request methods are not written especially for a specific request format! They just use the data format which was send to them without modification!

The method I used first:

req.query 

[..] only works with standard query strings, which are key=value pairs, which the URL you gave was not.[..]

The correct method to solve my problem is:

  url.parse(req.url).query

returns the complete parameter string of an URL which than has to be decoded manually:

  obj = JSON.parse(decodeURIComponent(query))

Here is the full explanation: https://github.com/strongloop/express/issues/2460

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.