安全地将JSON字符串转换为对象

时间:2008-09-05 00:12:02

标签: javascript json

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

显然,你可以用......之类的东西做不安全的事情。

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

...但是这使得我们容易受到包含其他代码的json字符串的影响,这对于简单评估来说似乎非常危险。

29 个答案:

答案 0 :(得分:1848)

JSON.parse(jsonString)是一种纯JavaScript方法,只要您能保证合理的现代浏览器。

答案 1 :(得分:867)

现在不推荐使用jQuery方法。请改用此方法:

let jsonObject = JSON.parse(jsonString);

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

如果您正在使用jQuery,请使用:

jQuery.parseJSON( jsonString );

这正是您所寻找的(请参阅jQuery documentation)。

答案 2 :(得分:151)

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

修改:此答案已过时,Jonathan's answer aboveJSON.parse(jsonString))现在是最佳答案

JSON.org有许多语言的JSON解析器,包括4个不同的Javascript语言。我相信大多数人会考虑json2.js他们的goto实现。

答案 3 :(得分:68)

使用以下link on MSDN中表示的简单代码。

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

并反转

var str = JSON.stringify(arr);

答案 4 :(得分:20)

我不确定其他方法可以做到,但这是你在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(),因为参数会清理传入的字符串。

答案 5 :(得分:18)

这似乎是个问题:

通过ajax websocket等接收输入,它总是以String格式 - 但你需要知道它是否是JSON.parsable。 Touble是,如果你总是通过JSON.parse运行它,程序可以继续“成功”但你仍然会看到控制台中出现的错误,其中包含可怕的“错误:意外令牌'x'”。

var data;

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

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

答案 6 :(得分:14)

如果您使用的是jQuery,您也可以$.getJSON(url, function(data) { });

然后您可以执行data.key1.somethingdata.key1.something_else

之类的操作

答案 7 :(得分:12)

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

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

答案 8 :(得分:10)

只是为了好玩,这是使用功能的方式:

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

答案 9 :(得分:9)

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

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

当您使用串行端口编程时,此方法确实有助于Nodej

答案 10 :(得分:7)

使用JSON.parse可能是最好的方法。以下是live demo

的示例
0

答案 11 :(得分:7)

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

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

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

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

使用 jQuery 中描述的documentation

JSON.parse(jsonString);

答案 12 :(得分:4)

我找到了一个更好的"方式:

在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'
});

答案 13 :(得分:2)

Booking -

json.parse将变为对象。

答案 14 :(得分:2)

如果我们有这样的字符串: “ {\”状态\“:1,\”令牌\“:\” 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

答案 15 :(得分:2)

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

JSON.parse(JSON.stringify(object))

答案 16 :(得分:2)

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 || {};
  }
};

答案 17 :(得分:1)

正式记录

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

<强>语法

JSON.parse(text[, reviver])

<强>参数

文本

要解析为JSON的字符串。有关JSON语法的说明,请参阅JSON对象。

reviver(可选)

如果是一个函数,这就规定了在返回之前如何转换最初由解析产生的值。

返回值

与给定JSON文本对应的Object。

<强>例外

如果要解析的字符串无效JSON,则抛出SyntaxError异常。

答案 18 :(得分:1)

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

您将输出为对象{result:true,count:1}。

为了使用该对象,你可以将它分配给变量让我们说obj: -

var obj = JSON.parse(response);

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

尝试运行命令

console.log(obj.result);

答案 19 :(得分: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 + ")");

答案 20 :(得分:0)

您还可以使用reviver功能进行过滤。

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

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

答案 21 :(得分: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 );
      }

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

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

答案 22 :(得分:0)

使用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"}

获取使用的值。运算符EXample:

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

要反向传输,请使用JSON.stringify()将JavaScript对象转换为字符串。

答案 23 :(得分: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

答案 24 :(得分:0)

/**
 * 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;
}

答案 25 :(得分:0)

JSON.parse是将字符串转换为对象的正确方法,但是如果所解析的字符串不是对象或字符串不正确,则会抛出错误,导致其余代码中断因此,将JSON.parse函数包装在

之类的try-catch中是理想的
try{
   let obj = JSON.parse(string);
}catch(err){
   console.log(err);
}

答案 26 :(得分:0)

性能

这个问题已经有了很好的答案,但是我对性能感到好奇,今天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上最快

enter image description here

详细信息

我执行4个测试用例:

  • 用于小型浅物HERE
  • 用于小型深空物体HERE
  • 用于大型浅物HERE
  • 用于大型深物HERE

以上测试中使用的对象来自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!

这是铬的示例结果

enter image description here

答案 27 :(得分:-1)

如果您的JavaScript位于Mootools,则JSON.parse将由框架匿名 用于将JSON字符串安全地转换为对象的有效syntax 应该是:

var object = JSON.decode(string[, secure]);

此外,JSON Request可以引发一个能够直接解析的对象 你可以在这里告诉它json raw data

http://jsfiddle.net/chetabahana/qbx9b5pm/

答案 28 :(得分:-1)

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

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