轻型和旧浏览器兼容纯javascript中JSON的替代方案

时间:2013-04-22 23:05:57

标签: javascript

我从存储在javascript var中的服务器获取文本响应。我完全控制了这个响应的格式。通常这个文本响应有3个我需要的元素,理想情况下我想使用json.parse来解决我的问题,如:

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

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

优雅而简单,但像IE8,7,6这样的older browsers不支持json.parse。在这一点上,我有两个可能的解决方案,当然是使用Jquery,但我不想要因为我想尽可能地保持我的代码小,而且两个可能正在使用像json2这样的库来处理我像jquery这样的不兼容问题,但是同样的问题,这么简单的函数代码太多了。

所以我认为最好的方法是将响应格式更改为true%1%ON,然后分成%,你怎么看?在我看来有点脏。

4 个答案:

答案 0 :(得分:3)

您可以从现有库中提取解析器的代码,而不是拥有所有内容,因为您只需要解析器。一个例子是从jQuery核心中挑出the implementation of $.parseJSON (lines 523-551)。显然它使用new Function方法而不是eval

答案 1 :(得分:0)

在我没有阅读这个问题而受到谴责之前,让我重新说一下:

在我看来,使用json2.js库(并不重要),不会导致显着的性能损失,特别是在最小化时也不会包含很多代码:

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")}}})()

您只需使用一行即可将其删除。为已经完成的事情编写自己的语法将花费大量时间来完成其他工作以完成项目。您将编写的任何代码都必须经过与此json库相同的严格测试,该库经过时间测试并证明可以正常工作。

这一行代码是3KB文件。

json on github

答案 2 :(得分:0)

好吧,就像你说的,你有两个选择:

  • 要么包含像JSON2这样的库(17KB未压缩,所以不是很大的负担)
  • 构建自己的小解析器

然后还有第三个选项是潜在的安全问题,但它可能会: 使用eval来评估json:

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

答案 3 :(得分:0)

您可以尝试json-sans-eval。它速度快而且很小(仅1.5Kb),但不验证您的JSON。