将JSON反序列化为JavaScript对象


266

我在使用AJAX访问的Java服务器应用程序中有一个字符串。它看起来像以下内容:

var json = [{
    "adjacencies": [
        {
          "nodeTo": "graphnode2",
          "nodeFrom": "graphnode1",
          "data": {
            "$color": "#557EAA"
          }
        }
    ],
    "data": {
      "$color": "#EBB056",
      "$type": "triangle",
      "$dim": 9
    },
    "id": "graphnode1",
    "name": "graphnode1"
},{
    "adjacencies": [],
    "data": {
      "$color": "#EBB056",
      "$type": "triangle",
      "$dim": 9
    },
    "id": "graphnode2",
    "name": "graphnode2"
}];

当从服务器提取字符串时,是否有一种简单的方法可以将其转换为活动的JavaScript对象(或数组)?还是我必须手动拆分字符串并手动构建对象?



Answers:


397

现代浏览器支持JSON.parse()

var arr_from_json = JSON.parse( json_string );

在不浏览器,您可以包括json2库中


这对于JSON中的日期字段如何起作用,例如{StartDate:“ \ / Date(1372575600000)\ /”}?
Philipp Munin

@PhilippMunin,您可以从JavaScript API使用此Date函数:new Date(parseInt(“ / Date(946681200000)/”。replace('/ Date(',``))));
Leo

或Map()对象等,您如何正确进行反序列化
Ewan

25

JSON的全部意义在于,无需执行任何操作即可将JSON字符串转换为本地对象。检查此链接

您可以使用eval(string)JSON.parse(string)

但是,eval是有风险的。从json.org:

评估功能非常快。但是,它可以编译和执行任何JavaScript程序,因此可能存在安全问题。当来源是可信任的且合格的时,将指示使用eval。使用JSON解析器要安全得多。在通过XMLHttpRequest的Web应用程序中,仅允许与提供该页面的源进行通信,因此它是可信任的。但这可能不称职。如果服务器的JSON编码不严格,或者没有严格验证其所有输入,则服务器可能会传递可能带有危险脚本的无效JSON文本。eval函数将执行脚本,释放其恶意。


1
我不明白这个风险。任何人都不能使用js调试器来注入和执行他们想要的任何脚本吗?
xr280xr

3
@ xr280xr是的,但这仅发生在其浏览器本地,而不是每个下载该网站的浏览器。
masterxilo 2014年

16

像jQuery一样!(精华)

function parseJSON(data) {
    return window.JSON && window.JSON.parse ? window.JSON.parse( data ) : (new Function("return " + data))(); 
}
// testing
obj = parseJSON('{"name":"John"}');
alert(obj.name);

这样,您不需要任何外部库,它仍然可以在旧的浏览器上运行。


7
看起来它回落到了eval()
LarsH 2011年

1
这是危险的,评估是邪恶的!
caesarsol '16

8

收集数组的所有项目并返回json对象

collectData: function (arrayElements) {

        var main = [];

        for (var i = 0; i < arrayElements.length; i++) {
            var data = {};
            this.e = arrayElements[i];            
            data.text = arrayElements[i].text;
            data.val = arrayElements[i].value;
            main[i] = data;
        }
        return main;
    },

要解析我们经历的相同数据

dummyParse: function (json) {       
        var o = JSON.parse(json); //conerted the string into JSON object        
        $.each(o, function () {
            inner = this;
            $.each(inner, function (index) {
                alert(this.text)
            });
        });

}

4

您也可以使用eval()JSON.parse()更安全,更轻松的方法,那么为什么呢?

好的工作

var yourJsonObject = JSON.parse(json_as_text);

我看不出您为什么要使用任何理由eval。这只会使您的应用程序处于危险之中。

这就是说-这也是可能的。

不好-但也可以

var yourJsonObject = eval(json_as_text);

为什么是eval个坏主意?

考虑以下示例。

某些第三方或用户提供了JSON字符串数据。

var json = `
[{
    "adjacencies": [
        {
          "nodeTo": function(){
            return "delete server files - you have been hacked!";
          }(),
          "nodeFrom": "graphnode1",
          "data": {
            "$color": "#557EAA"
          }
        }
    ],
    "data": {
      "$color": "#EBB056",
      "$type": "triangle",
      "$dim": 9
    },
    "id": "graphnode1",
    "name": "graphnode1"
},{
    "adjacencies": [],
    "data": {
      "$color": "#EBB056",
      "$type": "triangle",
      "$dim": 9
    },
    "id": "graphnode2",
    "name": "graphnode2"
}]
`;

您的服务器端脚本会处理这些数据。

使用JSON.parse

window.onload = function(){
  var placeholder = document.getElementById('placeholder1');
  placeholder.innerHTML = JSON.parse(json)[0].adjacencies[0].nodeTo;
}

会抛出:

Uncaught SyntaxError: Unexpected token u in JSON at position X. 

函数将不会执行。

你很安全

使用eval()

window.onload = function(){
  var placeholder = document.getElementById('placeholder1');
  placeholder.innerHTML = eval(json)[0].adjacencies[0].nodeTo;
}

将执行该函数并返回文本。

如果我用一种从您的网站文件夹中删除文件的无害功能代替了该功能,那么您就被黑了。在此示例中,不会抛出任何错误/警告。

你不安全。

我能够操纵JSON文本字符串,因此它充当将在服务器上执行的功能。

eval(JSON)[0].adjacencies[0].nodeTo 期望处理JSON字符串,但实际上,我们只是在服务器上执行了一个函数。

如果我们在将所有用户提供的数据传递给eval()函数之前在服务器端进行检查,但是为什么不仅仅使用内置工具来解析JSON并避免所有这些麻烦和危险,这也可以避免。


1

而且,如果您还希望反序列化的对象具有功能,则可以使用我的小工具:https : //github.com/khayll/jsmix

//first you'll need to define your model
var GraphNode = function() {};
GraphNode.prototype.getType = function() {
   return this.$type;
}

var Adjacency = function() {};
Adjacency.prototype.getData =n function() {
    return this.data;
}

//then you could say:
var result = JSMix(jsonData)
    .withObject(GraphNode.prototype, "*")
    .withObject(Adjacency.prototype, "*.adjacencies")
    .build();

//and use them
console.log(result[1][0].getData());

0

如果将服务器端的字符串粘贴到html中,则无需执行任何操作:

对于jsp中的纯Java:

var jsonObj=<%=jsonStringInJavaServlet%>;

对于jsp宽度支柱:

var jsonObj=<s:property value="jsonStringInJavaServlet" escape="false" escapeHtml="false"/>;

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.