XENON基于JSON变种

但是在用JSON的过程中,我遇到了一个问题——这个问题想必是大家多少都遇到过,那就是:JSON没有定义日期和时间的传递方式。
尽管在今年3月的一次更新中,json2.js已经增加了对Date函数和ISO-8601式的日期/时间格式,但各种常用的开发工具中对日期的支持还是五花八门、千奇百怪的,完全没有统一。
而且,除了日期/时间以外,个别时候我们还需要一些类或者函数的支持,而这些都是不被JSON所支持的。

可能有的人看到这里要问了:既然JSON不支持,那为什么不去用别的数据描述/传输方式呢?
原因是JSON本身就是JavaScript(其参考标准为ECMAScript)的功能子集,任何稍懂JavaScript的人都可以轻松地利用JSON。

解析JSON最简单的办法是直接使用eval函数将其作为JavaScript代码来执行,而JSON常常被用在互联网上的不同应用之间传递,所以直接将收到的JSON内容传入eval函数是具有很大的风险的,因此在RFC文档中严格规定了JSON的格式,并且给出了检验其安全性的办法。
而这个检验办法就禁止了函数的运行。

总而言之,因为JSON在使用上“偶尔”会有些不方便,所以我就开始动脑筋扩展JSON了。

在参考了RFC-4627、json2.js以及一些常见的JavaScript语法着色器以后,我发现:虽然json2.js已经有了对日期/时间的支持,但它所采用的语法分析的模式,这就意味着如果不是对语法分析有一定的了解,是很难对它进行扩展的;即使我稍微研习过一些语法分析的知识,想要扩展它也并非很容易的事情,更别谈日后的维护了。
所以我决定用RFC-4627中建议的较为简单的正则表达式过滤法。

这个扩展的基本实现是这样的:


代码如下:

function Xenon(){}
var protoXenon = Xenon.prototype;
protoXenon.xeval = function(s){
var al = [], vl = [], ol = {};
function $(i, v){
// i = parseInt(i);
// return ol[i] || (ol[i] = v);
return ol.propertyIsEnumerable(i) ? ol[i] : (ol[i] = v);
}
for(var n in this)
if(this.propertyIsEnumerable(n) && typeof this[n] == 'function')
al.push(n), vl.push(this[n]);
return eval('0,function(' + al + '){return ' + s + ';}').apply(this, vl);
};
protoXenon.safeXeval = function(s){
var T = this;
return (!/[^\),:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]/.test(
s.replace(/"(\\.|[^"\\])*"/g, '')
.replace(/([^\s:\[,\(]+?)\(/g,function($0, $1){
// return T.propertyIsEnumerable($1) ? '' : $1 + '(';
return T.propertyIsEnumerable($1) ? '' : '@';
})) || null) &&
this.xeval(s);
};

基本用法就是创建一个xenon对象,为其设置新的成员以启用扩展函数。
可以把扩展函数直接添加到xenon对象上,也可以在全局作用域中声明函数再在xenon对象上设置非函数类型的成员值。
例子:


代码如下:

var xenon = new Xenon();
xenon.Array = 0;
xenon.$ = 0;
xenon.date = function(s){return new Date(s);};
var o = xenon.safeXeval('{"list":Array(3,6,9),"created":$(1,date("Tue Jul 27 02:48:03 UTC+0800 2010")),"modified":$(1)}');
print(o.list);
print(o.created);
print(o.modified == o.created);

注:这个例子并不能直接作为JScript.NET代码执行,若要在JScript.NET中使用则必须将字符串"unsafe"作为第二个参数传递给eval函数。
注2:function关键字前增加“0,”是为了兼容于IE所使用的JScript引擎——当前的非CLI版本JScript引擎在其eval的实现中并不能正确地理解包围着函数定义的圆括号的意义,会因此引发语法错误。
在这个例子中使用了三个函数扩展:Array为全局作用域中的JavaScript内置函数;$是我在XENON中实现的内置功能,可以在多处引用同一个对象;而date则是对Date构造器的包装。
在XENON的实现中我没有让它支持new操作符创建新对象,我没发现有要用new而不能直接用扩展函数的理由。

关于名字:起初打算叫做xJson,但是后来想想觉得有点逊,改作XEON(eXtensible ECMAScript Object Notation)之后又发现好像是Intel的注册商标,所以在中间多加了个N变成了XENON(eXtensible Native ECMAScript Object Notation)。查了下字典,是个化学元素的名字……就这么凑合用吧。
关于安全性:在设计检验方法的过程中我尽可能测试了我所想得到的字符组合,力求避免注入问题。但是由于缺乏实践检验,我也不擅长语法分析之类的事情,所以可能并不是绝对安全。如果谁发现了其中的安全漏洞,可以通知我来改进它。
以后有时间我会做一个简单的从ECMAScript对象向XENON转换的函数;如果真的有很充裕的时间,也许我还会实现包含类名和构造器的转换过程。

(0)

相关推荐

  • XENON基于JSON变种

    但是在用JSON的过程中,我遇到了一个问题--这个问题想必是大家多少都遇到过,那就是:JSON没有定义日期和时间的传递方式. 尽管在今年3月的一次更新中,json2.js已经增加了对Date函数和ISO-8601式的日期/时间格式,但各种常用的开发工具中对日期的支持还是五花八门.千奇百怪的,完全没有统一. 而且,除了日期/时间以外,个别时候我们还需要一些类或者函数的支持,而这些都是不被JSON所支持的. 可能有的人看到这里要问了:既然JSON不支持,那为什么不去用别的数据描述/传输方式呢? 原因

  • jQuery基于json与cookie实现购物车的方法

    本文实例讲述了jQuery基于json与cookie实现购物车的方法.分享给大家供大家参考,具体如下: json 格式: [{'ProductID':ABC','Num':'1'},{'ProductID':DEF,'Num':'2'}] 这里使用到了 $.cookie这个插件.这个插件的代码在文章的最后 /* 添加商品及数量到购物车cookie中,返回当前商品在cookie中的总数 */ function AddToShoppingCar(id, num) { var _num = 1; if

  • 基于JSON和java对象的互转方法

    先说下我自己的理解,一般而言,JSON字符串要转为java对象需要自己写一个跟JSON一模一样的实体类bean,然后用bean.class作为参数传给对应的方法,实现转化成功. 上述这种方法太麻烦了.其实有一种东西叫jsonObject可以直接不用新建实体类bean,而实现转化,先说org.json.JSONObject这个JSONObject,贴上代码: import java.beans.IntrospectionException; import java.beans.Introspect

  • 基于Json序列化和反序列化通用的封装完整代码

    1. 最近项目已经上线了 ,闲暇了几天 想将JSON的序列化以及反序列化进行重新的封装一下本人定义为JSONHelp,虽然Microsoft 已经做的很好了.但是我想封装一套为自己开发的项目使用.方便后期的扩展以及开发使用. 2. 什么是 JSON ? JSON:JavaScript 对象表示法(JavaScript Object Notation).JSON 是存储和交换文本信息的语法.类似 XML.JSON 比 XML 更小.更快,更易解析.  现在开发Web应用程序 JSON 是 必不可少

  • 基于JSON数据格式详解

    JSON是行业内使用最为广泛的数据交换格式,在很多场景都有广泛的应用.JSON适用于进行数据交互的场景,典型的是Ajax中实现异步加载:为了支持跨平台.数据安全等的Web Service也可以使用(API接口返回值). JSON(JavaScript Object Notation)是一种完全独立于语言的.轻量级的数据交换格式.它基于JavaScript Programming Language, Standard ECMA-262 3rd Edition - December 1999的一个子

  • JavaScript跨域调用基于JSON的RESTful API

    1. 基本术语 AJAX(Asynchronous JavaScript And XML,异步JavaScript和XML):AJAX是一种用于创建快速动态网页的技术,通过在后台与服务器进行少量数据交换,AJAX可以使网页实现异步更新.这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新. JSON(JavaScript Object Notation):JSON是一种轻量级的数据交换格式,可以看成是由大括号包裹起来的多个"key/value"对,格式如下:{"f

  • 基于JSON格式数据的简单jQuery幻灯片插件(jquery-slider)

    jquery-slider是一款基于JSON格式数据的jQuery幻灯片插件.该幻灯片通过JSON数据来提供图片地址和描述信息等,你可以通过更换JSON数据来动态切换不同的图片. 在线预览     源码下载 使用方法 在页面中引入jquery和slider.js文件和font-awesome字体图标文件. <link rel='stylesheet' href='https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.4.0/css/font-

  • 基于json的jquery地区联动效果代码

    写这个东西的初衷是来之于新浪微博,在新浪微博帐号设置里面有个地区的选项,使用js写的,想把它的代码给截获下来,可是失望的是它的js代码压缩了,不过看到的里面json类型格式设计的挺好的,一般我们后台未做任何处理的json数据格式类似以下这样子的 [{"Code":3231,"Name":"长春市"}, {"Code":3232,"Name":"吉林市}] 如果有一万个地区,会多出几万个字符,这么奢

  • python基于json文件实现的gearman任务自动重启代码实例

    一:在gearman任务失败后,调用task_failed def task_failed(task, *args): info = '\n'.join(args) datetime = local_datetime() text = '{} FAILED:\n{}\n当前响应worker已关闭\n{}\n-->[{}]'.format(task, info, datetime, task) print(text) check_frequency(task) 二:打印失败信息后,调用check_

  • Spring Security基于json登录实现过程详解

    主要是重写attemptAuthentication方法 导入依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <dependency> <groupId>org.springframework.boot&l

随机推荐