XENON基于JSON变种


Posted in Javascript onJuly 27, 2010

但是在用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转换的函数;如果真的有很充裕的时间,也许我还会实现包含类名和构造器的转换过程。

Javascript 相关文章推荐
javascript编程起步(第四课)
Feb 27 Javascript
一组JS创建和操作表格的函数集合
May 07 Javascript
基于jQuery的输入框无值自动显示指定数据的实现代码
Jan 24 Javascript
简单的jquery左侧导航栏和页面选中效果
Aug 21 Javascript
深入理解JS正则表达式---分组
Jul 18 Javascript
JS获取checkbox的个数简单实例
Aug 19 Javascript
AngularJS extend用法详解及实例代码
Nov 15 Javascript
Angular2实现自定义双向绑定属性
Mar 22 Javascript
jQuery回调方法使用示例
Jun 26 jQuery
ES6深入理解之“let”能替代”var“吗?
Jun 28 Javascript
Vue中this.$nextTick的作用及用法
Feb 04 Javascript
ES2020 已定稿,真实场景案例分析
May 25 Javascript
JS遮罩层效果 兼容ie firefox jQuery遮罩层
Jul 26 #Javascript
腾讯与新浪的通过IP地址获取当前地理位置(省份)的接口
Jul 26 #Javascript
基于Jquery的文字滚动跑马灯插件(一个页面多个滚动区)
Jul 26 #Javascript
JQuery的Validation插件中Remote验证的中文问题
Jul 26 #Javascript
基于JQuery的一句代码实现表格的简单筛选
Jul 26 #Javascript
jQuery getJSON 处理json数据的代码
Jul 26 #Javascript
基于jQuery的可以控制左右滚动及自动滚动效果的代码
Jul 25 #Javascript
You might like
php下防止单引号,双引号在接受页面转义的设置方法
2008/09/25 PHP
[原创]php实现 data url的图片生成与保存
2016/12/04 PHP
基于php流程控制语句和循环控制语句(讲解)
2017/10/23 PHP
推荐dojo学习笔记
2007/03/24 Javascript
一段利用WSH获取登录时间的jscript代码
2008/05/11 Javascript
JavaScript入门教程(3) js面向对象
2009/01/31 Javascript
firefox下jquery iframe刷新页面提示会导致重复之前动作
2012/12/17 Javascript
js鼠标点击图片实现随机变换图片的方法
2015/02/16 Javascript
js实现浮动在网页右侧的简洁QQ在线客服代码
2015/09/04 Javascript
canvas绘制万花筒效果(代码分享)
2017/01/20 Javascript
JavaScript实现弹出广告功能
2017/03/30 Javascript
JavaScript结合HTML DOM实现联动菜单
2017/04/05 Javascript
jquery.masonry瀑布流效果
2017/05/25 jQuery
vue-router+vuex addRoutes实现路由动态加载及菜单动态加载
2017/09/28 Javascript
SpringBoot+Vue前后端分离,使用SpringSecurity完美处理权限问题的解决方法
2018/01/09 Javascript
vscode中eslint插件的配置(prettier配置无效)
2019/09/10 Javascript
微信小程序制作扭蛋机代码实例
2019/09/24 Javascript
再也不怕 JavaScript 报错了,怎么看怎么处理都在这儿
2020/12/09 Javascript
[10:18]2018DOTA2国际邀请赛寻真——找回自信的TNCPredator
2018/08/13 DOTA
python中while循环语句用法简单实例
2015/05/07 Python
Python语言描述连续子数组的最大和
2018/01/04 Python
Python中的单行、多行、中文注释方法
2018/07/19 Python
详解Python字典小结
2018/10/20 Python
python 使用turtule绘制递归图形(螺旋、二叉树、谢尔宾斯基三角形)
2019/05/30 Python
python调用自定义函数的实例操作
2019/06/26 Python
python实现连连看辅助(图像识别)
2020/03/25 Python
当我正在为表建立索引的时候,SQL Server 会禁止对表的访问吗
2014/04/28 面试题
路由表示做什么用的?在linux环境中怎么来配置一条默认路由?
2013/06/07 面试题
法学专业本科生自荐信范文
2013/12/17 职场文书
财务学生的职业生涯发展
2014/02/11 职场文书
2014国庆65周年领导讲话稿(3篇)
2014/09/21 职场文书
2014年村委会工作总结
2014/11/24 职场文书
就业导师推荐信范文
2015/03/27 职场文书
六一儿童节致辞
2015/07/31 职场文书
护理自荐信
2019/05/14 职场文书
利用js实现简单开关灯代码
2021/11/23 Javascript