给定一个JSON数据字符串,如何安全地将该字符串转换为JavaScript对象?

很明显,我可以用这样的方式来做这件事:

var obj = eval("(" + json + ')');

但这让我很容易受到包含其他代码的JSON字符串的攻击,简单地eval似乎非常危险。


当前回答

使用JSON.Parse()解析JSON字符串,数据将成为JavaScript对象:

JSON.parse(jsonString)

这里,JSON表示处理JSON数据集。

想象一下,我们从web服务器收到了以下文本:

'{ "name":"John", "age":30, "city":"New York"}'

要解析为JSON对象,请执行以下操作:

var obj = JSON.parse('{ "name":"John", "age":30, "city":"New York"}'); 

这里obj是相应的JSON对象,看起来像:

{ "name":"John", "age":30, "city":"New York"}

要获取值,请使用。操作员:

obj.name // John
obj.age //30

使用JSON.stringify()将JavaScript对象转换为字符串。

其他回答

表演

这个问题已经有了很好的答案,但我对性能很好奇,今天2020.09.21我在Chrome v85、Safari v13.1.2和Firefox v80上对MacOs HighSierra 10.13.6进行了测试,以确定所选的解决方案。

后果

eval/Function(A,B,C)方法在Chrome上很快(但对于大深度对象N=1000,它们会崩溃:“最大堆栈调用超过”)eval(A)在所有浏览器上都是快速/中等速度JSON.parse(D,E)在Safari和Firefox上速度最快

细节

我执行4个测试用例:

对于小的浅对象对于这里的小深对象对于这里的大型浅层物体对于这里的大深度对象

上述测试中使用的对象来自HERE

let obj_ShallowSmall={字段0:假,字段1:真,字段2:1,字段3:0,字段4:空,字段5:[],字段6:{},field7:“text7”,字段8:“text8”,}让obj_DepSmall={级别0:{级别1:{级别2:{级别3:{级别4:{级别5:{级别6:{第7级:{级别8:{第9级:[[[[[[[[]],}}}}}}}}},};让obj_ShallowBig=数组(1000).fill(0).reduce((a,c,i)=>(a['field'+i]=getField(i),a),{});让obj_DepBig=genDeepObject(1000);// ------------------//显示对象// ------------------console.log('obj_ShallowSmall:',JSON.stringify(obj_SharlowSmall));console.log('obj_DepSmall:',JSON.stringify(obj_DeepSmall));console.log('obj_ShallowBig:',JSON.stringify(obj_SharlowBig));console.log('obj_DepBig:',JSON.stringify(obj_DeepBig));// ------------------//助手// ------------------函数getField(k){设i=k%10;如果(i==0)返回false;如果(i==1)返回真;如果(i==2)返回k;如果(i==3)返回0;如果(i==4)返回null;如果(i==5)返回[];如果(i==6)返回{};如果(i>=7)返回“text”+k;}函数genDeepObject(N){//生成:{level0:{level1:{…levelN:{end:[[[…N次…['abc']…]]}}}}…}}让obj={};设o=obj;设arr=[];设a=arr;for(设i=0;i<N;i++){o['level'+i]={};o=o['level'+i];设aa=[];a.推(aa);a=aa;}a[0]=“公元前”;o['end']=arr;返回obj;}

下面的片段显示了所选的解决方案

//第三节:https://stackoverflow.com/q/45015/860099函数A(json){return eval(“(”+json+')');}// https://stackoverflow.com/a/26377600/860099函数B(json){return(新函数('return('+json+')'))()}//改进的https://stackoverflow.com/a/26377600/860099函数C(json){return函数('return('+json+')')()}//第三节:https://stackoverflow.com/a/5686237/860099函数D(json){返回JSON.parse(JSON);}//第三节:https://stackoverflow.com/a/233630/860099函数E(json){return$.parseJSON(json)}// --------------------//测试// --------------------让json=“{“a”:“abc”,“b”:“123”,“d”:[1,2,3],“e”:{”a“:1,”b“:2,”c“:3}}”;[A,B,C,D,E]映射(f=>{控制台日志(f.name+“”+JSON.stringfy(f(JSON)))})<script src=“https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js“></script>此shippet只显示性能测试中使用的函数,而不执行测试本身!

下面是铬的示例结果

官方文件:

方法解析JSON字符串,构造字符串所描述的JavaScript值或对象。可以提供可选的reviver函数,以便在返回结果对象之前对其执行转换。

语法:

JSON.parse(text[, reviver])

参数:

文本:要解析为JSON的字符串。有关JSON语法的描述,请参见JSON对象。

reviver(可选):如果是函数,这规定了在返回之前如何转换最初通过解析生成的值。

返回值

与给定JSON文本对应的Object。

例外情况

如果要分析的字符串不是有效的JSON,则引发SyntaxError异常。

使用parse()方法的最简单方法:

var response = '{"result":true,"count":1}';
var JsonObject= JSON.parse(response);

然后可以获得JSON元素的值,例如:

var myResponseResult = JsonObject.result;
var myResponseCount = JsonObject.count;

使用jQuery.parseJSON()文档中描述的jQuery:

JSON.parse(jsonString);

使用JSON.Parse()解析JSON字符串,数据将成为JavaScript对象:

JSON.parse(jsonString)

这里,JSON表示处理JSON数据集。

想象一下,我们从web服务器收到了以下文本:

'{ "name":"John", "age":30, "city":"New York"}'

要解析为JSON对象,请执行以下操作:

var obj = JSON.parse('{ "name":"John", "age":30, "city":"New York"}'); 

这里obj是相应的JSON对象,看起来像:

{ "name":"John", "age":30, "city":"New York"}

要获取值,请使用。操作员:

obj.name // John
obj.age //30

使用JSON.stringify()将JavaScript对象转换为字符串。

使用JSON.parse可能是最好的方法。

这里有一个例子

var jsonRes = '{ "students" : [' +
          '{ "firstName":"Michel" , "lastName":"John" ,"age":18},' +
          '{ "firstName":"Richard" , "lastName":"Joe","age":20 },' +
          '{ "firstName":"James" , "lastName":"Henry","age":15 } ]}';
var studentObject = JSON.parse(jsonRes);