1

Most of my AJAX calls just work with the daya attribute in jQuery to pass singular values. But sometimes I need to pass a structure in JSON to the server for further processing. I know how to, I know it works. But it seems to work only 90% of the time.

The setup is Railo 4.2 and IIS, both have most of their settings still as default. I'm also unable to reproduce this locally, where I have Coldfusion server instead of Railo. I'm also working in the Coldbox framework.

The jQuery code that sends the JSON data is as follows:

var oJSON = {'param1': param1, 'param2': param2, 'param3': param3};
$.ajax({
        type: "POST",
        url: uAjax + "?action=someurlparameter",
        data: JSON.stringify(oJson),
        contentType: "application/json; charset=utf-8",
        datatype: "json",
        success: function(oData)
        {
            // do something
        }
    });

The Coldfusion CFC that handles the incoming data does the following:

<cffunction name="cashup" returntype="struct" output="false" hint="handle json data">
    <cfargument name="event">
    <cfargument name="rc">
    <cfargument name="prc">

    <!--- get json data --->
    <cfset LOCAL.oJson = deserializeJSON(toString(getHttpRequestData().content)) />
    <cfreturn someService.someProcessing(LOCAL.oJson) />
</cffunction>

This seems pretty straight forward code to me. But for some reason 10% of the time these calls fail because the request body is empty. And I have no clue why. It can't be the data that is being sent, because clicking the button again, without refreshing the page, and thus retrying the ajax call, most of the time results in a good call, on that comes through WITH a filled request body.

edit 1:

sample data in json:

"MoneyLocation": {
      "MoneyLocationPaymentTypeCountList": [
       {
         "Amount": 175.28, 
         "Description": "CASH ", 
         "IdPaymentType": 2, 
         "ImageLocation": ""
       }, 
       {
         "Amount": 0, 
         "Description": "Generieke bon ", 
         "IdPaymentType": 62, 
         "ImageLocation": ""
       }
     ], 
     "IdTill": -1, 
     "IdMoneyLocation": 35
   }
dreagan
  • 2,426
  • 6
  • 24
  • 34
  • Seems unlikely to be the issue given it's a remote request and therefore the CFC instance should be transient, but you've got an un-`VAR`-ed variable `oJson` there. I'd at least sort that out. – Adam Cameron May 20 '14 at 11:21
  • What does your network tab tell you 10% of the time (when it sends an empty content) – Kevin B May 20 '14 at 19:36
  • @KevinB: The network tab tells me that data is being send correctly as JSON to the server in the request. Javascript sends a correct JSON object, but a cfdump of the getHttpRequestData().content is completely empty. – dreagan May 21 '14 at 06:58
  • @AdamCameron: forgot about scoping when writing the example. – dreagan May 21 '14 at 06:59
  • Cool. And there's nothing in any of Railo's logs suggesting a problem occurred? – Adam Cameron May 21 '14 at 07:41
  • nothing whatsoever. it's the only remaining (known) error at the moment, so the logs are failry empty (except for the actual logging we do). – dreagan May 21 '14 at 09:12
  • Have you dumped your cfc's arguments to see if they contain the data? – Miguel-F May 21 '14 at 14:07
  • I've already dumped all there is to dump. The request body never shows up, anywhere. Though I don't even see how that could be possible in this case.. – dreagan May 22 '14 at 06:19
  • Why are you stringify-ing the data param in the ajax call? Why not pass data as an object and the you won't need ``? – Binary Alchemist Jun 09 '14 at 17:53
  • I could give this a shot. perhaps stringifying in the AJAX call might interfere with the sending of the data. I'll let you know how it goes. – dreagan Jun 10 '14 at 06:50
  • @BinaryAlchemist: http://www.bennadel.com/blog/2207-posting-json-data-to-the-coldfusion-server-using-jquery.htm states that json serialisation needs to happen, otherwise jQuery will try and process it as a query. – dreagan Jun 13 '14 at 11:34
  • Have you been able to reproduce the issue? If so, please show us the reproducible test code and data. If not, have you been able to diagnose when the issue happens? Do you have sample data from when the issue occurs? – Miguel-F Jun 13 '14 at 11:59
  • @dreagan Json serialization would need to happen if you were passing more complex JSON... but the value of oJSON does not need to be stringified as is since it appears to just contain simple key-value pairs (unless param1, param2, param3 are objects or arrays). This still doesn't explain the empty request body though. Perhaps try the following on the ajax data option: `data: { thejson: JSON.stringify(oJson) }` In other words, assign the stringified json to its own named property ("thejson") in the ajax data property. – mathewbergt Jun 13 '14 at 23:50
  • @mathewbergt seems easy enough to try. I'll give it a go when I'm at work again. I'll let you know the results as soon as I can confirm the problem no longer exists. The json value is indeed more complex than is stated here. The parameters are objects and arrays. – dreagan Jun 14 '14 at 15:06
  • @Miguel-F I have indeed been able to reproduce. That's what bothers me even more. That is the reason I suspect it has little to do with the data or the encoding, since reposting the data via AJAX after the serverside error occurs usually goes through fine.. – dreagan Jun 14 '14 at 15:09
  • 1
    It would help us to help you if you could share the reproducible code and data. – Miguel-F Jun 15 '14 at 12:59
  • @mathewbergt: I've tried your suggestion, put it in production this morning, but didn't help. The issue remains the same. I've updated my question with sample data I got from more logging. – dreagan Jun 23 '14 at 11:09
  • I am having a similar issue using Django: http://stackoverflow.com/questions/22694407/empty-request-body-on-jquery-json-ajax-request – DavidM Jul 20 '14 at 18:38

1 Answers1

0

Working with a couple of other people on the Railo Google Group we've discovered that somewhere during the request the request body gets lost in time and space. sometimes. and very randomly. I'm no longer the only person to have experienced this issue and we've foudn that initially the request body is filled with the expected value.

By adding the following code to you onRequestStart() method in your application.cfc, you can again be sure of the values to expect in your request body:

request._body = ToString( GetHttpRequestData().content );

This is by no means a permanent solution. It poses no longer a threat to the integrity of the coldfusion application, but there is still something going awry behind it all. If we ever find out what is going on, I'll make sure to update this answer.

I also don't want to take credit for this bypass, I've not found this out myself. The good folks over at the Railo Google Group have pointed me in the right direction. But I want to be able to provide an answer to the question posed on stackoverflow as well.

dreagan
  • 2,426
  • 6
  • 24
  • 34