Most of the time, when we use jQuery to send data over to the server, it gets delivered as either a query string value or a form value. And, most of the time, this is exactly what we want. Occasionally, however, we might have data that doesn't quite conform to a simple set of name-value pairs. In such a situation - as I learned from Marak Squires at my Node.js training class - we can actually use jQuery to post a complex JSON packet as the HTTP request body. This JSON packet can then be parsed into native ColdFusion objects on the server-side.
When taking this kind of approach, there's a few things that we have to think about. The first is the content-type of the request. By default, jQuery makes requests with a content-type of "application/x-www-form-urlencoded". This HTTP header provides the server with the information it needs in order to properly parse the incoming request. When we send a JSON packet, however, we're not sending this kind of URL-encoded form data; rather, we're sending "json" data. As such, when sending a JSON packet to the server, we have to explicitly set the content-type to be:
If we don't do this, the ColdFusion server will attempt to parse the incoming HTTP request body as name-value pairs which will raise the following ColdFusion exception:
JRun Servlet Error
In addition to the content-type, we also have to think about the content value itself; or rather, the "data" value of the jQuery.ajax() invocation. If we set the data value to an Object, jQuery will serialize the object into name-value query-string pairs which will then be appending the URL. To prevent this from happening, we have to manually serialize our post data and pass it in as a string. If the data value is already a string, jQuery will not apply any additional processing.
In order to serialize our data object, we'll be using JSON.stringify() to turn the object into a JSON representation.
To see this in action, let's take a look at the following jQuery demo:
When we post this JSON packet to the server, it is being processed by the ColdFusion page, api.cfm:
<!--- Get the HTTP request body content. NOTE: We have to use toString() as an intermediary method call since the JSON packet comes across as a byte array (binary data) which needs to be turned back into a string before ColdFusion can parse it as a JSON value. ---> <cfset requestBody = toString( getHttpRequestData().content ) /> <!--- Double-check to make sure it's a JSON value. ---> <cfif isJSON( requestBody )> <!--- Echo back POST data. ---> <cfdump var="#deserializeJSON( requestBody )#" label="HTTP Body" /> </cfif>
As you can see, this API page simply extracts the incoming HTTP request body, deserializes it (the JSON packet) into native, server-side objects, and then echos them back to the client. When we run the above code, we get the following output:
As you can see, the ColdFusion server was able to parse the incoming JSON request body and dump it back to the client.
Most of the time, a standard jQuery.ajax() request is all that we need in order to provide effective client-server interaction. But sometimes, the data we need to post is more complex. In situations, such as JSON-RPC (JSON Remote Procedure Calls), nested objects can leave us with data that isn't easily serialized into a collection of name-value pairs. In such cases, we can still use jQuery to easily post JSON representations directly to the server where they can be parsed and processed more efficiently.
Want to use code from this post? Check out the license.