简体   繁体   中英

express.js 4 JSON parsing problems from GET request (request data from datatables)

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,%22val ue%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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM