There’s a lot of confusion among new developers on which format data should be sent to web server. Some (most?) developers create data/query string manually. But what if the desire or need is to send JSON data to server?
This Tech Tip will show how to send data as JSON to a 4D Web server. This Tech Tip is meant to be a basic guide to help 4D developers understand how to leverage JSON in exchanging data between client and server.
First question that might come to mind is "why to send JSON to server?" Is there any advantage of sending data as JSON? It depends mainly on what data is being sent to 4D. If the structure of data is really complex then JSON should be used in order to reduce parsing complexity.
When building a data/query string the data must first be converted to a string and once built the string has to be encoded using the javascript "encodeURI" function.
Because JSON accept all the native javascript data types without being converted to a string first, string conversion only happens once using the JSON.stringify function. Since the "Content-Type" has been set to "application/json" the URI encoding is handled automatically.
Below are two example javascript functions that preform a "POST" request to a web server, sending a json object. The first example use a generic XMLHttpRequest, the second uses jQuery's $.ajax function.
The important point in both of these functions is the setting of the HTTP header "Content-Type" to "application/json" and the converting the JSON object to a string using the javascript JSON.stringify function.
Please play close attention to the "xhr.send" in the first function and the "data:" in the second function. If only the JSON.stringify( jsonObj ) is sent 4D will receive the data in the web variable "value" array but the matching web variable "name" array will be blank.
By actually sending a JSON object (jQuery), {jsonStr: JSON.stringify( jsonObj )}, the web variable "name" array gets object name, in these examples "jsonStr", see the debugger image below.
AJAX generic
function myAjax( url, jsonObj ) { // construct an HTTP request var xhr = new XMLHttpRequest(); try { // Opera 8.0+, Firefox, Chrome, Safari xhr = new XMLHttpRequest(); } catch (e) { // Internet Explorer Browsers try{ xhr = new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) { try { xhr = new ActiveXObject("Microsoft.XMLHTTP"); } catch (e) { // Something went wrong alert("Your browser broken!"); return false; } } } xhr.open('POST', url, true); // tell the server that JSON is being sent xhr.setRequestHeader('Content-Type', 'application/json; charset=UTF-8'); // encode the JSON string into a URI query string var jsonStr = encodeURI( "jsonStr=" + JSON.stringify( jsonObj ) ); // callback function to handle the server response xhr.onreadystatechange = function() { if (xhr.readyState == 4) { if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) { var jsonStr = xhr.responseText; // Javascript function JSON.parse to parse the JSON string var jsonObj = JSON.parse( jsonStr ); // Now do something with the JSON object myMethod( jsonObj ); } else { console.log( xhr.statusText) ; alert( "Error getting " + target.name + ": " + xhr.statusText + ", code: "+ xhr.status ); } } } // send the collected data as encodedURI JSON string xhr.send( jsonStr ); } |
AJAX using jQuery
function myAjax( url, jsonObj ) { // using jQuery, note jQuery handles URI encoding automatically $.ajax({ type: 'POST', url: url, contentType: 'application/json; charset=utf-8', data: {jsonStr: JSON.stringify( jsonObj )}, dataType: 'json', // The type of data jQuery expects back from the server. success: function( data ) { // do something } }); }; |
JSON object received and processed by 4D
What if ...
- In the AJAX generic function the JSON object is sent directly in the manner xhr.send( jsonObj );? A javascript error will be generated in the client.
- In the AJAX generic function the JSON object is sent directly in the manner xhr.send( endcodeURI( jsonObj ));? The web variable names array will contain "[object Object]" and the matchiong web variable variables array will be empty.
- In the AJAX generic function the JSON object is sent in the manner as the jQuery "data" element, xhr.send( endcodeURI( "{jsonStr:" + JSON.stringify( jsonObj )+"}" ));? The web variable names array will contain "{jsonStr:{"PageNo":1,"PerPage":5}}" and the matchiong web variable variables array will be empty.
- In the AJAX generic function the JSON object is sent in the manner of a Query string such as, xhr.send( endcodeURI( "jsonStr=" + JSON.stringify( jsonObj ));? This is the only way to have the JSON object sent to 4D as an "entact object" and for it to have matching web variables arrays.
jQuery is robust enough to handle various ways the JSON object is added to its ajax "data" key. If the object itself is passed, jQuery will parse the object into a Query string before it is sent. The keys will be in the web variable names array and the values in the web variable values arrays. In this caee, the ajax "contentType" key should not be set to "application/json," but to "application/x-www-form-urlencoded" instead.
Submitting Forms as JSON
The easiest way at the writing of this Tech Tip to submit form data as JSON is to use the jQuery .serialize() or .serializeArray() functions. Once the new W3C HTML JSON form submission specification is adapted, and HTML form element will be able to have the attribute <form enctype='application/json'>, thus making the form data submitted as JSON much simpler and more common.