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

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

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

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


当前回答

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

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

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

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

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

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

我知道,老问题是,但是没有人注意到这个解决方案,因为它使用了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元素(例如数据属性)的配置设置。

这似乎是一个问题:

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

var data;

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

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