473,387 Members | 1,592 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,387 software developers and data experts.

How to escape the "&" in a JSON.stringfy() ajax call?

Claus Mygind
571 512MB
I am having trouble escaping the & in a JSON.stringfy() ajax call. I don't even know if I am stating the problem correctly here.

In my app I have linked json2.js from http://www.JSON.org/json2.js 2010-08-25(see attached file) to my app.

Then I have created an ajax call in the app to my server_side app in which I invoke the JSON.stringify(dataObj). My "dataObj" is an Associative Array. If one of the array element values contains the "&" the queryString variable is truncated. I was under the impression that JSON.stringify() would escape any control characters. but I am wrong.

What baffles me more is the fact I have even commented out the link to json2.js in my page header and the app does not crash when it get to the JSON.stringify() command.
Expand|Select|Wrap|Line Numbers
  1. <!-- <script type="text/javascript" language="JavaScript"    src="json2.js"></script>
  2.  -->
I don't know if it is because I am using FireFox 3.6.13. I thought that I had read that they have now included JSON right in FireFox.

The question remains "How do I escape the & or any other control character, when it occurs in a value"? I would hope this would be part of the json process.

Here is the offending name/value pair:
"TITLE":"Earthwork & Excavating Contracts Manager"

This is the string as transmitted
"TITLE":"Earthwork

Here is my ajax code.
Expand|Select|Wrap|Line Numbers
  1. //a public array used to store the ajax call response
  2. var    aCallBack = new Array();
  3.  
  4. function myAjax (callApp, dataObj, getOrSave) {
  5.  
  6.     this.makeCall = function (callApp, dataObj, getOrSave) {
  7.         var queryString  = "&appData="+JSON.stringify(dataObj);
  8.  
  9.                     //create ajax object
  10.         var request = window.ActiveXObject ?
  11.             new ActiveXObject('Microsoft.XMLHTTP') :
  12.             new XMLHttpRequest;
  13.  
  14.             //assemble data
  15.             var url = callApp+'?timeStamp=' + new Date().getTime();
  16.  
  17.             //actually make call and get response in chkStateChange function
  18.             request.open("POST", url, true);
  19.             request.onreadystatechange = function chkStateChange(){
  20.                                             if (request.readyState == 4) {
  21.                                                 if (request.status == 200) {
  22.                                                     processResponse(request.responseText);
  23.                                                 }
  24.                                             }
  25.                                          };
  26.             request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
  27.             request.send( queryString );
  28.     };
  29.  
  30.     var processResponse = function (response) {
  31.  
  32.         aCallBack = response.split(';');
  33.  
  34.         if ( aCallBack[0] == "An error occured") { 
  35.             eAlert  = aCallBack[0]+"\n";
  36.             for (var i = 1; i < aCallBack.length; i++ )
  37.             {
  38.                 eAlert += aCallBack[i]+"\n";
  39.             }
  40.             alert( eAlert );
  41.         }else if (aCallBack[0] == "Record Saved")    {
  42.             alert("temp message Record Saved. /n look in _Navigation.js");        
  43.         }else{
  44.             updatePage();
  45.         }
  46.     };
  47. }
  48.  
  49. //ajax object created
  50. var ajax = new myAjax();
  51.  
Attached Files
File Type: zip json2.zip (5.4 KB, 205 views)
Jan 25 '11 #1

✓ answered by Claus Mygind

It turns out a better option is to simply encode the & when sending the JSON string to the server using POST.

The array I created is encoded by the:
var queryString = "appData="+JSON.stringify(dataObj);
(see code below)

the stringify function of JSON will encode all the special characters execpt the &. if the actual data contains an & the ajax call fails because the & will split the data at that point thinking it is a 2nd name/value pair.

What I can't understand is by comparison I am a novice at this why can I not find any reference on the net about how to handle the & in the data transmitted. The link I posted earlier uses a different format than JSON when transmitting data from the client to the server. So you are not taking advantage of JSON when the data arrives at the server. If there is more links that explain how to handle the &, I sure would like to read about it.

I made the following change to my code and got it to work

I build my array in the following manner:
Expand|Select|Wrap|Line Numbers
  1. /*
  2. -----------------------------------------
  3. I call this function to read all the data 
  4. nodes/elements on the form I want to save
  5. ------------------------------------------
  6. */
  7. function saveData(form)
  8. {
  9.     var dataObj = new Object();
  10.  
  11.     for (var i = 0; i < form.elements.length; i++)
  12.     {
  13.         var element = form.elements[i];
  14.         var type = element.type;
  15.         if (type == "checkbox")
  16.         {
  17.             if (element.checked)
  18.             {
  19.                 dataObj[element.id] ="T";
  20.             }else{
  21.                 dataObj[element.id] ="F";
  22.             }
  23.         }
  24.         else if (type == "radio")
  25.         {
  26.             if (element.checked)
  27.             {
  28.                 dataObj[element.id] = element.value;
  29.             }
  30.         }
  31.         else if (type == "hidden" || type == "password" || type == "text" ||
  32.                  type == "textarea")
  33.         {
  34. //text nodes which could contain the & are checked and encoded if necessary
  35.                 dataObj[element.id] = encode(element.value);
  36.         }
  37.         else if (type == "select-one" || type == "select-multiple")
  38.         {
  39.  
  40.             xText += form.element.selectedIndex.value;
  41.                 for (var j = 0; j < element.options.length; j++)
  42.                 {
  43.                     if (element.options[j].selected )
  44.                     {
  45. //text nodes which could contain the & are checked and encoded if necessary
  46. dataObj[element.id] = encode(element.options[j].value);
  47.                     }
  48.                 }
  49.         }
  50.     }
  51.  
  52. /*
  53. -------------------------------
  54. Here I make an ajax call to the 
  55. server via the function/method 
  56. I previously bound to the 
  57. variable ajax, see code below.
  58. -------------------------------
  59. */
  60.    ajax.makeCall("myServerSideApp.php", dataObj);
  61.  
  62. }
  63.  
  64. function encode(strVal)
  65. {
  66. /*
  67. -------------------------------------------
  68. using a regular expression I search 
  69. for the & and encode it with %26.  
  70.  
  71. This will automatically be decoded 
  72. in my php server side app when I call "json_decode($_REQUEST['appData'], true);",
  73. where appData is the JSON object 
  74. I transmitted.
  75. --------------------------------------------
  76. */
  77.     if (strVal.indexOf('&') > -1)
  78.     {
  79.         var searchStr = "&";
  80.         var replaceStr = "%26";
  81.         var re = new RegExp(searchStr, "g");
  82.         var result = strVal.replace(re, replaceStr);
  83.     }else{
  84.         var result = strVal;
  85.     }
  86.  
  87.     return result;
  88. }
  89.  
  90.  
  91. /*
  92. ----------------------------------------------
  93. Here is the actual ajax function called above
  94. -----------------------------------------------
  95. */
  96.  
  97. //a public array used to store the ajax call response
  98. var    aCallBack = new Array();
  99.  
  100. function myAjax (callApp, dataObj) {
  101.  
  102.     this.makeCall = function (callApp, dataObj) {
  103.         var queryString  = "appData="+JSON.stringify(dataObj);
  104.  
  105.         //create ajax object
  106.         var request = window.ActiveXObject ?
  107.             new ActiveXObject('Microsoft.XMLHTTP') :
  108.             new XMLHttpRequest;
  109.  
  110.             //create url
  111.             var url = callApp+'?timeStamp=' + new Date().getTime();
  112.  
  113.             //actually make call and get response in chkStateChange function
  114.             request.open("POST", url, true);
  115.             request.onreadystatechange = function chkStateChange(){
  116.                                             if (request.readyState == 4) {
  117.                                                 if (request.status == 200) {
  118.                                                     processResponse(request.responseText);
  119.                                                 }
  120.                                             }
  121.                                          };
  122.             request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
  123.             request.send( queryString );
  124.     };
  125.  
  126.     var processResponse = function (response) {
  127.  
  128.         aCallBack = response.split(';');
  129.  
  130.         if ( aCallBack[0] == "An error occured") { 
  131.             eAlert  = aCallBack[0]+"\n";
  132.             for (var i = 1; i < aCallBack.length; i++ )
  133.             {
  134.                 eAlert += aCallBack[i]+"\n";
  135.             }
  136.             alert( eAlert );
  137.         }else if (aCallBack[0] == "Record Saved")    {
  138.             alert("message Record Saved.");        
  139.         }else{
  140.             updatePage();
  141.         }
  142.     };
  143. }
  144.  
  145. /*
  146. -----------------------------
  147. ajax object created and bound 
  148. to my myAjax function/method
  149. -----------------------------
  150. */
  151. var ajax = new myAjax();
  152.  
  153.  

9 37201
Oralloy
988 Expert 512MB
Claus,

Sorry for being quick, but I didn't take the time to completely analyze what you wrote. No insult intended, I'm searching for an answer and found your post.

Do you need to JSON escape the "&", or HTML escape it? Remember that there are a number of magic characters, that must be escaped in HTTP "GET" queries. Not just the "&" character, but the "+" and " " characters, as well. So what you probably need to do is to HTML encode your arguments. There are standard ways to do this, but I'm not an AJAX Guru, so I'll leave that to smarter folk than I.

Also, JSON is delivered as a standard part of recent browsers. You can test this out by building a trivial page like so:
Expand|Select|Wrap|Line Numbers
  1. <html>
  2.  <head>
  3.   <title>JSON Test</title>
  4.  </head>
  5.  <body>
  6.   JSON Test<br>
  7.   JSON.stringify = "<span id='myJSON' />"
  8.  </body>
  9. </html>
  10. <script type="text/javascript" language="JavaScript">
  11.   alert(JSON.stringify);
  12.   document.getElementById('myJSON').innerHTML = String(JSON.stringify);
  13. </script>
Cheers!
Oralloy
Jan 25 '11 #2
Claus Mygind
571 512MB
Thanks for the reply. Not sure what I was suppose to get from that. Cut and pasted the code in my FireFox 3.6.13 and got this result. Is this the intended and could you explain the outcome in a little more depth, so I have a better understanding?

This was the output I got:
JSON Test
JSON.stringify = "function stringify() { [native code] }
Jan 25 '11 #3
Oralloy
988 Expert 512MB
What that tells you is that JSON is already incorporated in your browser, so you don't have to include the json2 script library as part of your web page. Basically JSON is so useful, that it's part of the default scripting environment now days.

Also, as a test, try substituting '&ampl;' for '&' in your server response and see if that helps any. In general you should HTML encode all responses to queries, as '&' is not the only magic character you'll encounter.

Luck!
Oralloy
Jan 25 '11 #4
Claus Mygind
571 512MB
Thanks again for the quick explanation.

Just a couple of items here.

1) I am doing a POST not a GET
2) the array I am passing is being assembled on the client side not the server side.

& alone is the offending character. So I don't think I can substitute & with &ampl;

I also see now that & is not one of the offending characters to JSON. So that kind of leads back to your original thought about doing an HTML escape.

As explained here:
http://bytes.com/topic/javascript/an...haracters-json

I am pretty confident that my JSON.stingify() works because I tested it with the " double quote.

So I wonder if I will have to run the standard javaScript encode and decode when I create the array?

Also I would like to know if the code snippet I posted is correctly written? Meaning when it gets called, it indeed does stringify the array?
Jan 25 '11 #5
Oralloy
988 Expert 512MB
Claus,

Your basic problem is HTTP parameter parsing.

What happens is that the server recieves the parameter string queryString, which looks like "&appData="+JSON.stringify(dataObj).

Then the server parses the string based on HTTP's rules. To whit, '&' separates separates parameters, '=' separates parameter names from values, etc... Basically the rules are exactly the same as for a "GET" query; the only difference being that the parameters are sent in the body of the query, and not the URL part.

Nothing in HTTP's parameter specifications gives special meaning to quote (') characters in the parameter string. So, even though your '&' character is embedded in a well-formed JSON string, and is fully quoted, HTTP doesn't care. Similarly you will find that addition symbols, '+', are mapped to spaces.

The way to deal with this is to URL encode the parameter string by mapping special characters ('&', '+', ' ', '=', etc...) which occur in the parameter names and values into their appropriate transmission encodings.

Here are a couple links that might help:
Query_string#URL_encoding
Percent-encoding

Hopefully this helps some.

What surprises me is that the request object doesn't have a method which accepts "key/value" pair and encodes them automagically. That would save a lot of grief in the long run.

Oh well.

Good Luck! Let me know how it turns out.
Oralloy
Jan 25 '11 #6
Claus Mygind
571 512MB
Thank you for a very thorough reply. I get it now and I will just encode the data when I form the array.

Likewise I will decode the data on the server side.

I just did not know that when you do ajax POST that it would be different than a standard POST when you submit a form.
Jan 26 '11 #7
Claus Mygind
571 512MB
Well it is nice to know someone has already invented the wheel.

http://www.openjs.com/scripts/data/u..._encoded_data/

Looks like it should be a simple copy and paste operation for me.

Thanks again Oralloy for your outstanding help.
Jan 26 '11 #8
Oralloy
988 Expert 512MB
Claus,

I'm glad that you found a complete solution. It looks like the key to his code is the "encodeURIComponent" call at the bottom of his script. I didn't know about that method, so I'm glad you found it.

Cheers!
Jan 26 '11 #9
Claus Mygind
571 512MB
It turns out a better option is to simply encode the & when sending the JSON string to the server using POST.

The array I created is encoded by the:
var queryString = "appData="+JSON.stringify(dataObj);
(see code below)

the stringify function of JSON will encode all the special characters execpt the &. if the actual data contains an & the ajax call fails because the & will split the data at that point thinking it is a 2nd name/value pair.

What I can't understand is by comparison I am a novice at this why can I not find any reference on the net about how to handle the & in the data transmitted. The link I posted earlier uses a different format than JSON when transmitting data from the client to the server. So you are not taking advantage of JSON when the data arrives at the server. If there is more links that explain how to handle the &, I sure would like to read about it.

I made the following change to my code and got it to work

I build my array in the following manner:
Expand|Select|Wrap|Line Numbers
  1. /*
  2. -----------------------------------------
  3. I call this function to read all the data 
  4. nodes/elements on the form I want to save
  5. ------------------------------------------
  6. */
  7. function saveData(form)
  8. {
  9.     var dataObj = new Object();
  10.  
  11.     for (var i = 0; i < form.elements.length; i++)
  12.     {
  13.         var element = form.elements[i];
  14.         var type = element.type;
  15.         if (type == "checkbox")
  16.         {
  17.             if (element.checked)
  18.             {
  19.                 dataObj[element.id] ="T";
  20.             }else{
  21.                 dataObj[element.id] ="F";
  22.             }
  23.         }
  24.         else if (type == "radio")
  25.         {
  26.             if (element.checked)
  27.             {
  28.                 dataObj[element.id] = element.value;
  29.             }
  30.         }
  31.         else if (type == "hidden" || type == "password" || type == "text" ||
  32.                  type == "textarea")
  33.         {
  34. //text nodes which could contain the & are checked and encoded if necessary
  35.                 dataObj[element.id] = encode(element.value);
  36.         }
  37.         else if (type == "select-one" || type == "select-multiple")
  38.         {
  39.  
  40.             xText += form.element.selectedIndex.value;
  41.                 for (var j = 0; j < element.options.length; j++)
  42.                 {
  43.                     if (element.options[j].selected )
  44.                     {
  45. //text nodes which could contain the & are checked and encoded if necessary
  46. dataObj[element.id] = encode(element.options[j].value);
  47.                     }
  48.                 }
  49.         }
  50.     }
  51.  
  52. /*
  53. -------------------------------
  54. Here I make an ajax call to the 
  55. server via the function/method 
  56. I previously bound to the 
  57. variable ajax, see code below.
  58. -------------------------------
  59. */
  60.    ajax.makeCall("myServerSideApp.php", dataObj);
  61.  
  62. }
  63.  
  64. function encode(strVal)
  65. {
  66. /*
  67. -------------------------------------------
  68. using a regular expression I search 
  69. for the & and encode it with %26.  
  70.  
  71. This will automatically be decoded 
  72. in my php server side app when I call "json_decode($_REQUEST['appData'], true);",
  73. where appData is the JSON object 
  74. I transmitted.
  75. --------------------------------------------
  76. */
  77.     if (strVal.indexOf('&') > -1)
  78.     {
  79.         var searchStr = "&";
  80.         var replaceStr = "%26";
  81.         var re = new RegExp(searchStr, "g");
  82.         var result = strVal.replace(re, replaceStr);
  83.     }else{
  84.         var result = strVal;
  85.     }
  86.  
  87.     return result;
  88. }
  89.  
  90.  
  91. /*
  92. ----------------------------------------------
  93. Here is the actual ajax function called above
  94. -----------------------------------------------
  95. */
  96.  
  97. //a public array used to store the ajax call response
  98. var    aCallBack = new Array();
  99.  
  100. function myAjax (callApp, dataObj) {
  101.  
  102.     this.makeCall = function (callApp, dataObj) {
  103.         var queryString  = "appData="+JSON.stringify(dataObj);
  104.  
  105.         //create ajax object
  106.         var request = window.ActiveXObject ?
  107.             new ActiveXObject('Microsoft.XMLHTTP') :
  108.             new XMLHttpRequest;
  109.  
  110.             //create url
  111.             var url = callApp+'?timeStamp=' + new Date().getTime();
  112.  
  113.             //actually make call and get response in chkStateChange function
  114.             request.open("POST", url, true);
  115.             request.onreadystatechange = function chkStateChange(){
  116.                                             if (request.readyState == 4) {
  117.                                                 if (request.status == 200) {
  118.                                                     processResponse(request.responseText);
  119.                                                 }
  120.                                             }
  121.                                          };
  122.             request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
  123.             request.send( queryString );
  124.     };
  125.  
  126.     var processResponse = function (response) {
  127.  
  128.         aCallBack = response.split(';');
  129.  
  130.         if ( aCallBack[0] == "An error occured") { 
  131.             eAlert  = aCallBack[0]+"\n";
  132.             for (var i = 1; i < aCallBack.length; i++ )
  133.             {
  134.                 eAlert += aCallBack[i]+"\n";
  135.             }
  136.             alert( eAlert );
  137.         }else if (aCallBack[0] == "Record Saved")    {
  138.             alert("message Record Saved.");        
  139.         }else{
  140.             updatePage();
  141.         }
  142.     };
  143. }
  144.  
  145. /*
  146. -----------------------------
  147. ajax object created and bound 
  148. to my myAjax function/method
  149. -----------------------------
  150. */
  151. var ajax = new myAjax();
  152.  
  153.  
Feb 4 '11 #10

Sign in to post your reply or Sign up for a free account.

Similar topics

1
by: Grzegorz Smith | last post by:
Hi everyone. Does anyone know is it possible to check if ajax call was redirect? i mean I connect by Ajax to one URL but I'm redirected to other url. Is there a way to check that my request was...
1
by: Chaprasi | last post by:
Hi, I was wondering how I can achieve to display a 'Please wait loading...' message only if the ajax call is taking more than a second. The message should only appear if the Ajax call is...
2
by: Zeba | last post by:
Hi guys! I'm new to JS / Ajax; I've been trying to do an Ajax call to my Webservice ( I'm using C# for code-behind). I'm not using any of the libraries available. I am sending my CustID to the...
3
by: wendallsan | last post by:
Hi All, I've stumped myself writing an app that uses Prototype and a bit of PHP. Here is what I have: I have a custom class named Default_county_init_data that, upon initialization makes...
3
by: KDawg44 | last post by:
Hi, I would like a verification image for new sign ups on a website. Is there a way to call the PHP script through an AJAX call and have the image passed back and then display? Is there a way...
5
RamananKalirajan
by: RamananKalirajan | last post by:
Hi guys, I am having a problem in Prototypejs AJAX, I am triggering the AJAX call and in the option i am using like the folowing code: new Ajax.Request(connection.url, { method:...
3
by: rbansalit | last post by:
Hi all I am making a very simple ajax call. But I am not getting any message from sever. <html> <body> <script type="text/javascript"> function ajaxFunction()
5
by: samarinder | last post by:
I am displaying the results by iterating the list in div tag say "results" in my case.For refining of search i am using ajax call. But when i am getting response back from this below snippet ...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.