1438

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

显然,我可以通过以下方式不安全地执行此操作:

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

但这让我容易受到包含其他代码的 JSON 字符串的影响,简单地评估似乎非常危险。

4

27 回答 27

2072

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

于 2011-04-16T11:45:21.977 回答
892

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

let jsonObject = JSON.parse(jsonString);

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

如果您使用的是 jQuery,请使用:

jQuery.parseJSON( jsonString );

这正是您正在寻找的(参见 jQuery文档)。

于 2010-09-02T14:07:07.757 回答
165

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

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

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

于 2008-09-05T00:13:52.627 回答
77

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

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

并扭转它:

var str = JSON.stringify(arr);
于 2013-12-15T23:26:31.860 回答
25

这似乎是一个问题:

通过 Ajax websocket 等接收的输入,它将是字符串格式,但您需要知道它是否是JSON.parsable. JSON.parse问题是,如果你总是通过"Error: unexpected token 'x'".

var data;

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

data || (data = {
  message: 'Server error, please retry'
});
于 2013-04-29T07:37:16.990 回答
24

我不确定其他方法可以做到这一点,但这是你在Prototype (JSON tutorial)中的做法。

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

使用 true 作为参数调用evalJSON()会清理传入的字符串。

于 2008-09-05T00:13:51.440 回答
20

如果您使用的是jQuery,您还可以使用:

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

然后你可以做类似的事情

data.key1.something
data.key1.something_else

等等

于 2008-10-24T13:57:10.490 回答
17

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

 jsonObject = (new Function('return ' + jsonFormatData))()
于 2014-10-15T08:11:30.117 回答
16
$.ajax({
  url: url,
  dataType: 'json',
  data: data,
  success: callback
});

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

于 2010-05-06T06:23:08.867 回答
14

使用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);
于 2015-04-22T09:40:23.497 回答
10

尝试将此方法与此 Data 对象一起使用。例如:Data='{result:true,count:1}'

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

当您使用串行端口编程时,此方法在 Nodejs 中确实很有帮助

于 2014-07-15T18:53:54.920 回答
9

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

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

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

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

如文档中所述使用jQuery :jQuery.parseJSON()

JSON.parse(jsonString);
于 2016-02-20T01:00:42.333 回答
5

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

在 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'
});
于 2015-02-18T13:38:07.537 回答
4

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 || {};
  }
};
于 2017-02-14T20:47:16.593 回答
3

JSON.parse()将传递给函数的任何 JSON 字符串转换为 JSON 对象。

为了更好地理解它,F12请在浏览器中按打开“检查元素”并转到控制台编写以下命令:

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}

为了使用该对象,您可以将其分配给变量,也许obj

var obj = JSON.parse(response);

通过使用obj和点 ( .) 运算符,您可以访问 JSON 对象的属性。

尝试运行命令:

console.log(obj.result);
于 2016-12-03T15:32:36.053 回答
3
JSON.parse(jsonString);

json.parse 将变为对象。

于 2016-12-19T13:05:06.490 回答
3

官方文档

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

句法:

JSON.parse(text[, reviver])

参数:

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

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

返回值

与给定 JSON 文本对应的 Object。

例外

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

于 2017-12-20T01:47:45.153 回答
3

用 解析 JSON 字符串JSON.parse(),数据变成一个 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

将 JavaScript 对象转换为带有JSON.stringify().

于 2018-08-13T02:33:45.467 回答
3

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

"{\"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
于 2019-03-15T08:15:01.690 回答
2

将对象转换为 JSON,然后对其进行解析,对我有用,例如:

JSON.parse(JSON.stringify(object))
于 2017-06-19T16:28:40.853 回答
1

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

用 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-02-23T05:34:13.277 回答
1

表现

这个问题已经有了很好的答案,但我对性能很好奇,今天 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 = {
  field0: false,
  field1: true,
  field2: 1,
  field3: 0,
  field4: null,
  field5: [],
  field6: {},
  field7: "text7",
  field8: "text8",
}

let obj_DeepSmall = {
  level0: {
   level1: {
    level2: {
     level3: {
      level4: {
       level5: {
        level6: {
         level7: {
          level8: {
           level9: [[[[[[[[[['abc']]]]]]]]]],
  }}}}}}}}},
};

let obj_ShallowBig = Array(1000).fill(0).reduce((a,c,i) => (a['field'+i]=getField(i),a) ,{});


let obj_DeepBig = genDeepObject(1000);



// ------------------
// Show objects
// ------------------

console.log('obj_ShallowSmall:',JSON.stringify(obj_ShallowSmall));
console.log('obj_DeepSmall:',JSON.stringify(obj_DeepSmall));
console.log('obj_ShallowBig:',JSON.stringify(obj_ShallowBig));
console.log('obj_DeepBig:',JSON.stringify(obj_DeepBig));




// ------------------
// HELPERS
// ------------------

function getField(k) {
  let i=k%10;
  if(i==0) return false;
  if(i==1) return true;
  if(i==2) return k;
  if(i==3) return 0;
  if(i==4) return null;
  if(i==5) return [];
  if(i==6) return {};  
  if(i>=7) return "text"+k;
}

function genDeepObject(N) {
  // generate: {level0:{level1:{...levelN: {end:[[[...N-times...['abc']...]]] }}}...}}}
  let obj={};
  let o=obj;
  let arr = [];
  let a=arr;

  for(let i=0; i<N; i++) {
    o['level'+i]={};
    o=o['level'+i];
    let aa=[];
    a.push(aa);
    a=aa;
  }

  a[0]='abc';
  o['end']=arr;
  return obj;
}

下面的片段展示了选择的解决方案

// src: https://stackoverflow.com/q/45015/860099
function A(json) {
  return eval("(" + json + ')');
}

// https://stackoverflow.com/a/26377600/860099
function B(json) {
  return (new Function('return ('+json+')'))()
}


// improved https://stackoverflow.com/a/26377600/860099
function C(json) {
  return Function('return ('+json+')')()
}

// src: https://stackoverflow.com/a/5686237/860099
function D(json) {
  return JSON.parse(json);
}

// src: https://stackoverflow.com/a/233630/860099
function E(json) {
  return $.parseJSON(json)
}



 
// --------------------
// TEST
// --------------------

let json = '{"a":"abc","b":"123","d":[1,2,3],"e":{"a":1,"b":2,"c":3}}';

[A,B,C,D,E].map(f=> {  
  console.log(
    f.name + ' ' + JSON.stringify(f(json))
  )})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
This shippet only presents functions used in performance tests - it not perform tests itself!

这是 chrome 的示例结果

在此处输入图像描述

于 2020-09-21T09:11:33.737 回答
0

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

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

欲了解更多信息,请阅读JSON.parse

于 2017-07-26T08:58:53.963 回答
0

较老的问题,我知道,但是没有人通过使用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 );
      }

这更安全一些,因为它在函数内部执行,而不是直接在您的代码中编译。所以如果里面有函数声明,就不会绑定到默认的window对象。

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

于 2018-02-19T01:27:00.967 回答
0

概括:

Javascript(浏览器和 NodeJS)有一个内置JSON对象。在这个对象上有 2 种方便的方法来处理JSON. 它们是:

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

其他应用:

除了为了非常方便地处理它们之外,JSON它们还可以用于其他方式。这两种JSON方法的结合使我们能够非常轻松地对数组或对象进行深度克隆。例如:

let arr1 = [1, 2, [3 ,4]];
let newArr = arr1.slice();

arr1[2][0] = 'changed'; 
console.log(newArr); // not a deep clone

let arr2 = [1, 2, [3 ,4]];
let newArrDeepclone = JSON.parse(JSON.stringify(arr2));

arr2[2][0] = 'changed'; 
console.log(newArrDeepclone); // A deep clone, values unchanged

于 2018-08-18T10:00:42.880 回答
-2

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

         export function safeJsonParse(str: string) {
               try {
                 return JSON.parse(str);
                   } catch (e) {
                 return str;
                 }
           }
于 2018-05-30T06:31:48.527 回答
-2
/**
 * Safely turning a JSON string into an object
 *
 * @param {String} str - JSON String
 * @returns deserialized object, false if error
 */
export function jsonParse(str) {
  let data = null;
  try {
    data = JSON.parse(str);
  } catch (err) {
    return false;
  }
  return data;
}
于 2019-12-30T05:28:56.340 回答