0

I am escaping & and = before parsing to an object like this:

var obb = parseJSON('{"' + text.replace(/&/g, "\",\"").replace(/=/g,"\":\"") + '"}');

When the object is created i get:

obb.name
obb.date
obb.text

Inside obb.text i want to revert the escape done above..

I've tried:

text.replace(/\&/g, "&").replace(/\=/g, "=")

When i run the following on obb.text

obb.text = decodeURIComponent(escape(obb.text));

I get parse errors

But does not seem to work

Any ideas?

Jeffrey Blake
  • 9,659
  • 6
  • 43
  • 65
Alosyius
  • 8,771
  • 26
  • 76
  • 120
  • 4
    What are you trying to accomplish? What is your input and expected output? I have a feeling you don't need to do what you're doing. – Joe Enos Apr 25 '13 at 16:05
  • From the start text is a url like this: name=hello&date=2013&text=hello = bye bye? % lalala " aa".... so text.text can contain all kinds of characters thats why i am trying to handle them so i do not get parse errors – Alosyius Apr 25 '13 at 16:07
  • 1
    Why not just [URI encode](https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/encodeURI) them? – ajp15243 Apr 25 '13 at 16:10
  • text.text is sent form the server like this: unescape(encodeURIComponent(body)) – Alosyius Apr 25 '13 at 16:11
  • and in order to parse it into an object i need the text.replace(/&/g, "\",\"").replace(/=/g,"\":\"") on my client – Alosyius Apr 25 '13 at 16:12
  • I think that all i need is a way to undo replace(/&/g, "\",\"").replace(/=/g,"\":\"") within text.text and ill be good.. but cant figure out how to get it to work – Alosyius Apr 25 '13 at 16:13
  • Parsing `x-www-form-urlencoded` can be done in a more reliable fashion than abusing JSON decoding :) – Ja͢ck Apr 25 '13 at 16:13
  • hmm how? :)) been banging my head against the wall on this prob for some time – Alosyius Apr 25 '13 at 16:15
  • possible duplicate of [How can I get query string values?](http://stackoverflow.com/questions/901115/how-can-i-get-query-string-values) – Bergi Apr 25 '13 at 16:19

2 Answers2

2

Rather than keeping your fingers crossed that your output data does not contain anything that would cause the JSON parser to barf up, consider this method based on HTTP RFC parameter parsing. The RFC RFC (2616) states the following rules:

  • All fields are separated by &
  • All field names are before an =, values after =, value is optional
  • [] denotes "one more element to this as an array",

They also tentatively suggest the following rule, which I will offer you a choice on: - A parameter without [] overwrites its previous versions if submitted (this is not followed by all webservers and is the matter of HTTP fragmentation/pollution attacks, by the way)

We're going to parse following this exact structure, assuming that stuff has been properly character-encoded. The start of the code should look like this:

var myObj = {};
var k = myPostbackContent.split("&");
for (var i = 0; i < k.length; i++) {
  var kinfo = k[i].split("=");
  var key = kinfo[0];
  if (kinfo[1] !== undefined) {
     var value = kinfo[1];
  };
  if (key.substr(-2) == "[]") {
     key = key.substr(0,key.length-2);
     if (myObj[key] === undefined) myObj[key] = [];
     if (myObj[key] instanceof Array) myObj[key].push(value);
  }
  else {

The following part is dependent on your assumptions:

  • If you would like your elements to overwrite each other, put in the else the following version:

      myObj[key] = value;
    
  • If, instead, you would prefer to have the first instance of an element have precedence, put the following:

     if (myObj[key] === undefined) myObj[key] = value;
    
  • If, like IIS, you'd prefer to have the element auto-append to a string separated by ,, use the following:

     if (myObj[key].length) myObj[key] += ",";
     myObj[key] += value;
    

I've built a little TinkerIO script to show you how all three works. If this is not what you were looking for, do let me know. The default behaviour is "overwrite", by the way.

This method can be applied in reverse to go from an object to an URI-encoded string, by the way. Just loop through your object's properties and go by key=value, joining all the elements with a &.

Sébastien Renauld
  • 19,203
  • 2
  • 46
  • 66
1

As long as your text parameter is always at the end of the string you could do something like this:

var obb = {};
obb.name = text.match(/name=([^&]+)/)[1];
obb.date = text.match(/date=([^&]+)/)[1];
obb.text = text.match(/text=(.+)/)[1];

DEMO

Aust
  • 11,552
  • 13
  • 44
  • 74