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

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

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

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


我不确定是否有其他方法可以做到这一点,但以下是在Prototype(JSON教程)中如何做到的。

new Ajax.Request('/some_url', {
  method:'get',
  requestHeaders: {Accept: 'application/json'},
  onSuccess: function(transport){
    var json = transport.responseText.evalJSON(true);
  }
});

使用true作为参数调用evalJSON()将净化传入字符串。


这个答案适用于IE<7,对于现代浏览器,请查看上面Jonathan的答案。

这个答案已经过时,Jonathan上面的答案(JSON.parse(jsonString))现在是最好的答案。

JSON.org有多种语言的JSON解析器,包括四种不同的JavaScript解析器。我相信大多数人都会考虑将json2.js作为他们的goto实现。


如果使用jQuery,还可以使用:

$.getJSON(url, function(data) { });

然后你可以做类似的事情

data.key1.something
data.key1.something_else

etc.


$.ajax({
  url: url,
  dataType: 'json',
  data: data,
  success: callback
});

回调传递返回的数据,该数据将是JSON结构定义的JavaScript对象或数组,并使用$.parseJSON()方法进行解析。


jQuery方法现在已被弃用。请改用此方法:

let jsonObject = JSON.parse(jsonString);

使用已弃用的jQuery功能的原始答案:

如果您使用jQuery,只需使用:

jQuery.parseJSON( jsonString );

这正是您想要的(请参阅jQuery文档)。


只要你能保证一个相当现代的浏览器,JSON.parse(jsonString)就是一种纯JavaScript方法。


这似乎是一个问题:

通过Ajax websocket等接收的输入,它将是字符串格式,但您需要知道它是否是JSON.parsable。问题是,如果您始终通过JSON.parse运行它,程序可能会“成功”继续运行,但您仍然会看到控制台中抛出一个错误,显示可怕的“错误:意外标记'x'”。

var data;

try {
  data = JSON.parse(jqxhr.responseText);
} catch (_error) {}

data || (data = {
  message: 'Server error, please retry'
});

使用“JSON.parse()”中的简单代码示例:

var jsontext = '{"firstname":"Jesper","surname":"Aaberg","phone":["555-0100","555-0120"]}';
var contact = JSON.parse(jsontext);

并将其反转:

var str = JSON.stringify(arr);

请尝试使用此Data对象的方法。ex:Data=“{result:true,count:1}”

try {
  eval('var obj=' + Data);
  console.log(obj.count);
}
catch(e) {
  console.log(e.message);
}

当您使用串行端口编程时,此方法在Nodejs中非常有用


为了好玩,这里有一种使用函数的方法:

 jsonObject = (new Function('return ' + jsonFormatData))()

我找到了一个“更好”的方法:

在CoffeeScript中:

try data = JSON.parse(jqxhr.responseText)
data ||= { message: 'Server error, please retry' }

在Javascript中:

var data;

try {
  data = JSON.parse(jqxhr.responseText);
} catch (_error) {}

data || (data = {
  message: 'Server error, please retry'
});

使用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);

使用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字符串转换为JSON对象。

要更好地理解它,请按F12在浏览器中打开“Inspect Element”,然后转到控制台编写以下命令:

var response = '{"result":true,"count":1}'; //sample json object(string form)
JSON.parse(response); //converts passed string to JSON Object.

现在运行命令:

console.log(JSON.parse(response));

您将得到一个Object{result:true,count:1}的输出。

为了使用该Object,可以将其分配给变量,可能是obj:

var obj = JSON.parse(response);

通过使用obj和点(.)操作符,您可以访问JSON对象的财产。

尝试运行以下命令:

console.log(obj.result);

JSON.parse(jsonString);

json.parse将变为object。


JSON解析总是一个难题。如果输入不符合预期,则会抛出错误并使您正在执行的操作崩溃。

您可以使用下面的小函数来安全地解析输入。即使输入无效或已经是一个对象,它也始终会转换对象,这在大多数情况下更好:

JSON.safeParse = function (input, def) {
  // Convert null to empty object
  if (!input) {
    return def || {};
  } else if (Object.prototype.toString.call(input) === '[object Object]') {
    return input;
  }
  try {
    return JSON.parse(input);
  } catch (e) {
    return def || {};
  }
};

将对象转换为JSON,然后解析它,对我来说很有用,比如:

JSON.parse(JSON.stringify(object))

您也可以使用reviver函数进行过滤。

var data = JSON.parse(jsonString, function reviver(key, value) {
   //your code here to filter
});

有关详细信息,请阅读JSON.parse。


官方文件:

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

语法:

JSON.parse(text[, reviver])

参数:

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

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

返回值

与给定JSON文本对应的Object。

例外情况

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


我知道,老问题是,但是没有人注意到这个解决方案,因为它使用了new Function(),一个返回数据的匿名函数。


举个例子:

 var oData = 'test1:"This is my object",test2:"This is my object"';

 if( typeof oData !== 'object' )
  try {
   oData = (new Function('return {'+oData+'};'))();
  }
  catch(e) { oData=false; }

 if( typeof oData !== 'object' )
  { alert( 'Error in code' ); }
 else {
        alert( oData.test1 );
        alert( oData.test2 );
      }

这稍微安全一点,因为它在函数内部执行,而不直接在代码中编译。因此,如果其中有函数声明,它将不会绑定到默认的窗口对象。

我使用它来简单快速地“编译”DOM元素(例如数据属性)的配置设置。


试试这个。这是用打字机写的。

export function safeJsonParse(str: string) {
    try {
        return JSON.parse(str);
    } catch (e) {
        return str;
    }
}

使用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对象转换为字符串。


摘要:

Javascript(浏览器和NodeJS)有一个内置的JSON对象。在这个Object上有两种处理JSON的方便方法。它们如下:

JSON.parse()将JSON作为参数,返回JS对象JSON.stringify()将JS对象作为参数返回JSON对象

其他应用:

除了非常方便地处理JSON之外,它们还可以用于其他方式。两种JSON方法的结合使我们可以非常容易地制作数组或对象的深度克隆。例如:

设arr1=[1,2,[3,4]];让newArr=arr1.slice();arr1[2][0]=“已更改”;console.log(newArr);//不是深度克隆设arr2=[1,2,[3,4]];让newArrDeepclon=JSON.parse(JSON.stringify(arr2));arr2[2][0]=“已更改”;console.log(newArrDeepclone);//深度克隆,值不变


如果我们有这样的字符串:

"{\"status\":1,\"token\":\"65b4352b2dfc4957a09add0ce5714059\"}"

那么我们可以简单地使用JSON.parse两次将该字符串转换为JSON对象:

var sampleString = "{\"status\":1,\"token\":\"65b4352b2dfc4957a09add0ce5714059\"}"
var jsonString= JSON.parse(sampleString)
var jsonObject= JSON.parse(jsonString)

我们可以使用以下方法从JSON对象中提取值:

// instead of last JSON.parse:
var { status, token } = JSON.parse(jsonString);

结果将是:

status = 1 and token = 65b4352b2dfc4957a09add0ce5714059

仅针对不同输入类型的封面解析

使用JSON.Parse()解析数据,数据将成为JavaScript对象。

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

当对从数组派生的JSON使用JSON.parse()时,该方法将返回JavaScript数组,而不是JavaScript对象。

var myArr = JSON.parse(this.responseText);
console.log(myArr[0]);

JSON中不允许使用日期对象。约会时做这样的事

var text = '{ "name":"John", "birth":"1986-12-14", "city":"New York"}';
var obj = JSON.parse(text);
obj.birth = new Date(obj.birth);

JSON中不允许使用函数。如果需要包含函数,请将其写成字符串。

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

表演

这个问题已经有了很好的答案,但我对性能很好奇,今天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只显示性能测试中使用的函数,而不执行测试本身!

下面是铬的示例结果


另一种选择

const json=“{”水果“:”菠萝“,”手指“:10}”让j0s,j1s,j2s,j3sconsole.log(`{“${j0s=“fruit”}”:“${j1s=“菠萝”}”,“${j2s=“fingers”}”:${j3s=“10”}}`)


在JavaScript中解析JSON的推荐方法是使用JSON.parse()

出身背景

JSON API是在ECMAScript 5中引入的,目前已在99%以上的浏览器中实现(按市场份额)。

jQuery曾经有一个$.parseJSON()函数,但在jQuery 3.0中已弃用。无论如何,在很长一段时间里,它只是JSON.parse()的包装器。

实例

const json=“{”城市“:”波士顿“,”人口“:500000}”;const object=JSON.parse(JSON);console.log(object.city,object.population);


浏览器兼容性

所有主要浏览器都支持JSON.parse吗?

差不多,是的(见参考资料)。