DomingoSL
DomingoSL

Reputation: 15494

Light and old-browsers compatible alternative for JSON in pure javascript

Im getting a text response from my server stored in a javascript var. I have complete control of the format of this response. Normally this text response have 3 elements I need, ideally i will like to use json.parse to solve my problems like:

var json = '{"result":true,"count":1, "state":"ON"}',
obj = JSON.parse(json);

alert(obj.result);
alert(obj.count);
alert(obj.state);

Elegant and simple, but older browsers like IE8,7,6 do not support json.parse. At this point I have two possible solutions, one of course is to use Jquery, but i dont want because i want to keep my code small as possible, and two could be using a library like json2 that handles for me the incompatibility issues like jquery does, but then again, same problem, too much code for such a simple function.

So I think the best approach will be to change the response format to something like true%1%ON and then split around %, what do you think? seems to me a bit dirty.

Upvotes: 1

Views: 447

Answers (4)

Joseph
Joseph

Reputation: 119867

You can pluck out the code for the parser from an existing library instead of having everything, since you only need the parser. An example would be plucking out the implementation of $.parseJSON (lines 523-551) from the jQuery core. Apparently it uses the new Function approach instead of eval.

Upvotes: 3

SomeShinyObject
SomeShinyObject

Reputation: 7811

Before I get berated on not reading the question, let me rephrase:

Using the json2.js library, in my opinion (not that it matters), would not lead to a significant performance loss it is also not a lot of code to include especially when minimized:

if(typeof JSON!=="object"){JSON={}}(function(){"use strict";function f(e){return e<10?"0"+e:e}function quote(e){escapable.lastIndex=0;return escapable.test(e)?'"'+e.replace(escapable,function(e){var t=meta[e];return typeof t==="string"?t:"\\u"+("0000"+e.charCodeAt(0).toString(16)).slice(-4)})+'"':'"'+e+'"'}function str(e,t){var n,r,i,s,o=gap,u,a=t[e];if(a&&typeof a==="object"&&typeof a.toJSON==="function"){a=a.toJSON(e)}if(typeof rep==="function"){a=rep.call(t,e,a)}switch(typeof a){case"string":return quote(a);case"number":return isFinite(a)?String(a):"null";case"boolean":case"null":return String(a);case"object":if(!a){return"null"}gap+=indent;u=[];if(Object.prototype.toString.apply(a)==="[object Array]"){s=a.length;for(n=0;n<s;n+=1){u[n]=str(n,a)||"null"}i=u.length===0?"[]":gap?"[\n"+gap+u.join(",\n"+gap)+"\n"+o+"]":"["+u.join(",")+"]";gap=o;return i}if(rep&&typeof rep==="object"){s=rep.length;for(n=0;n<s;n+=1){if(typeof rep[n]==="string"){r=rep[n];i=str(r,a);if(i){u.push(quote(r)+(gap?": ":":")+i)}}}}else{for(r in a){if(Object.prototype.hasOwnProperty.call(a,r)){i=str(r,a);if(i){u.push(quote(r)+(gap?": ":":")+i)}}}}i=u.length===0?"{}":gap?"{\n"+gap+u.join(",\n"+gap)+"\n"+o+"}":"{"+u.join(",")+"}";gap=o;return i}}if(typeof Date.prototype.toJSON!=="function"){Date.prototype.toJSON=function(e){return isFinite(this.valueOf())?this.getUTCFullYear()+"-"+f(this.getUTCMonth()+1)+"-"+f(this.getUTCDate())+"T"+f(this.getUTCHours())+":"+f(this.getUTCMinutes())+":"+f(this.getUTCSeconds())+"Z":null};String.prototype.toJSON=Number.prototype.toJSON=Boolean.prototype.toJSON=function(e){return this.valueOf()}}var cx=/[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,escapable=/[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,gap,indent,meta={"\b":"\\b","   ":"\\t","\n":"\\n","\f":"\\f","\r":"\\r",'"':'\\"',"\\":"\\\\"},rep;if(typeof JSON.stringify!=="function"){JSON.stringify=function(e,t,n){var r;gap="";indent="";if(typeof n==="number"){for(r=0;r<n;r+=1){indent+=" "}}else if(typeof n==="string"){indent=n}rep=t;if(t&&typeof t!=="function"&&(typeof t!=="object"||typeof t.length!=="number")){throw new Error("JSON.stringify")}return str("",{"":e})}}if(typeof JSON.parse!=="function"){JSON.parse=function(text,reviver){function walk(e,t){var n,r,i=e[t];if(i&&typeof i==="object"){for(n in i){if(Object.prototype.hasOwnProperty.call(i,n)){r=walk(i,n);if(r!==undefined){i[n]=r}else{delete i[n]}}}}return reviver.call(e,t,i)}var j;text=String(text);cx.lastIndex=0;if(cx.test(text)){text=text.replace(cx,function(e){return"\\u"+("0000"+e.charCodeAt(0).toString(16)).slice(-4)})}if(/^[\],:{}\s]*$/.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,"]").replace(/(?:^|:|,)(?:\s*\[)+/g,""))){j=eval("("+text+")");return typeof reviver==="function"?walk({"":j},""):j}throw new SyntaxError("JSON.parse")}}})()

You can drop it in using only one line and be done with it. Writing your own syntax for something that's already been done is going to take a lot of time away from doing the other work to finish your project. Any code that you will write will have to go through the same rigorous testing as this json library which has been time tested and proven to work.

This one line of code is a 3KB file.

json on github

Upvotes: 1

Ken Herbert
Ken Herbert

Reputation: 5236

You could try json-sans-eval. It is fast and small (only 1.5Kb), but does not validate your JSON.

Upvotes: 0

Kenneth
Kenneth

Reputation: 28737

Well, like you said, you have two options:

  • either include a library like JSON2 (which is 17KB uncompressed, so not a big burden)
  • Build your own little parser

And then there's a third option which is potential security issue, but it might do: use eval to evaluate the json:

var json = '{"result":true,"count":1, "state":"ON"}';
obj = eval(json);

Upvotes: 0

Related Questions