没有eval的JSON日期?

时间:2013-12-30 22:30:31

标签: javascript json date

简短说明:

是否有一个javascript JSON转换器可以保存日期并且使用eval? 例如:

var obj1 = { someInt: 1, someDate: new Date(1388361600000) };
var obj2 = parseJSON(toJSON(obj1));
//obj2.someDate should now be of type Date and not String
//(like in ordinary json-parsers).

详细说明:

我认为大多数使用JSON的人已经遇到了如何传输日期的问题:

var obj = { someInt: 1, someDate: new Date(1388361600000) }

将此转换为JSON并返回时,日期突然变为String:

JSON.parse(JSON.stringify(obj)) 
== { someInt: 1, someDate: "2013-12-30T00:00:00.000Z" }

这是一个巨大的缺点,因为您无法使用JSON轻松提交日期。总是需要一些后处理(你需要知道在哪里寻找日期)。

然后,微软在JSON规范中找到了一个漏洞,按照惯例,编码日期如下:

{"someInt":1,"someDate":"\/Date(1388361600000)\/"}

这方面的亮点在于,现在有一种确定的方法可以从有效JSON字符串中的Date中告诉String:编码的字符串将从不包含子字符串@" /" (反斜杠后跟斜线,不要与逃逸的斜线相混淆)。因此,知道此约定的解析器现在可以安全地创建Date对象。

如果解析器不知道此约定,则日期将被解析为无害且可读的字符串" /日期(1388361600000)/"。

缺点是似乎没有解析器可以在不使用eval的情况下读取它。 Microsoft提出以下方式来阅读此内容:

var obj = eval("(" + s.replace(/\"\\\/Date\((\d+)\)\\\/\"/g, function (match, time) { return "new Date(" + time + ")"; }) + ")");

这就像一个魅力:你永远不必再关心JSON中的日期了。但它使用非常不安全的eval方法。

您是否知道任何即使使用的解析器在不使用eval的情况下获得相同的结果?

修改 关于调整编码的优点的评论中存在一些混淆。 我设置了一个jsFiddle,应该明确意图:http://jsfiddle.net/AJheH/

2 个答案:

答案 0 :(得分:1)

我不同意腺体的评论,即JSON是字符串的表示法,不能代表对象。 Json是复合数据类型的表示法,它必须采用序列化对象的形式,尽管原始类型只能是整数,浮点数,字符串或布尔值。 (更新:如果你曾经处理过意大利面条编码的XML,那么你会很感激,也许这也是一件好事!)

如果他们现在认为创建一个包含数据类型来描述类型的非标准符号是更好的想法,那么大概是匈牙利语符号已经失去了对微软的青睐。

“eval”本身并不邪恶 - 它使得解决一些问题变得更加容易 - 但在使用它时很难实现良好的安全性。实际上,默认情况下,它已通过内容安全策略禁用。

恕我直言,归结为将日期存储为1388361600000或“2013-12-30T00:00:00.000Z”。恕我直言,后者具有明显更多的语义价值 - 脱离上下文显然是日期+时间,而后者可能几乎任何事情。两者都可以通过ECMAscript Date对象进行解析,而无需使用eval。是的,这确实需要代码来处理数据 - 但是如果不对其进行解析,您可以使用某种数据做什么?他只有时间才能看到这是一个无模式数据库的优势 - 但公平地说这是一个很大的问题。

答案 1 :(得分:0)

问题是以下代码行,这里是一个示例函数,看看parseWithDate函数,将脚本添加到页面并将以下行更改为它将起作用。

http://www.asp.net/ajaxlibrary/jquery_webforms_serialize_dates_to_json.ashx

var parsed1 = JSON.parse(s1); // changed to below
var parsed1 = JSON.parseWithDate(s1);

更新了有效http://jsfiddle.net/GLb67/1/

的jsFiddle