将JSON反序列化为JavaScript对象
我在使用AJAX访问的Java服务器应用程序中有一个string。 它看起来如下所示:
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" }];
当string被从服务器中取出时,是否有一种简单的方法可以将它变成一个活跃的JavaScript对象(或数组)? 或者我必须手动拆分string,并手动build立我的对象?
现代浏览器支持JSON.parse()
。
var arr_from_json = JSON.parse( json_string );
在没有的浏览器中,可以包含json2
库 。
JSON的重点在于JSONstring可以在不做任何事情的情况下转换为本地对象。 检查这个链接
您可以使用eval(string)或JSON.parse(string)。
但是,eval是有风险的。 从json.org
eval函数非常快。 但是,它可以编译和执行任何JavaScript程序,所以可能存在安全问题。 当来源是可信和有能力的时候,使用评估。 使用JSONparsing器要安全得多。 在XMLHttpRequest上的Web应用程序中,通信只允许提供该页面的相同来源,因此它是可信的。 但它可能不能胜任。 如果服务器的JSON编码不严格,或者如果不严格validation所有的input,那么它可能会传递无效的JSON文本,这些文本可能带有危险的脚本。 eval函数会执行这个脚本,释放它的恶意。
像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);
这样你就不需要任何外部库,它仍然可以在旧的浏览器上工作。
收集数组的所有项目并返回一个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; },
parsing相同的数据,我们经历这样的
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) }); }); }
你也可以使用eval()
但是JSON.parse()
是更安全更简单的方法,那么为什么呢?
好和工作
var yourJsonObject = JSON.parse(json_as_text);
我看不出有什么理由为什么要使用eval
。 它只会让你的应用程序处于危险之中
这就是说 – 这也是可能的。
不好 – 但也有效
var yourJsonObject = eval(json_as_text);
为什么eval
是一个坏主意?
考虑下面的例子。
某些第三方或用户提供了JSONstring数据。
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; }
将执行该函数并返回文本。
如果我将这个无害的functionreplace成从网站文件夹中删除文件的function,那么你已经被黑客入侵了。 这个例子中没有错误/警告。
你不安全。
我能够操纵一个JSON文本string,所以它作为一个函数,将在服务器上执行。
eval(JSON)[0].adjacencies[0].nodeTo
期望处理一个JSONstring,但实际上,我们只是在我们的服务器上执行一个函数。
如果我们在传递给eval()
函数之前服务器端检查所有用户提供的数据,但是为什么不使用内置工具来parsingJSON并避免所有这些麻烦和危险?
如果你也想要反序列化的对象有function,你可以使用我的小工具: 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());
如果将string粘贴到服务器端,则不需要做任何事情:
对于jsp中的普通java:
var jsonObj=<%=jsonStringInJavaServlet%>;
对于jsp宽度struts:
var jsonObj=<s:property value="jsonStringInJavaServlet" escape="false" escapeHtml="false"/>;
我认为这应该有所帮助:
另外,文档也certificate你可以使用require()作为json文件: https : //www.bennadel.com/blog/2908-you-can-use-require-to-load-json-javascript-object-notation-files -in-节点js.htm
var jsonfile = require("./path/to/jsonfile.json"); node = jsonfile.adjacencies.nodeTo; node2 = jsonfile.adjacencies.nodeFrom; node3 = jsonfile.adjacencies.data.$color; //other things.