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 相关文章推荐
谷歌浏览器 insertCell与appendChild的区别
Feb 12 Javascript
获取元素距离浏览器周边的位置的方法getBoundingClientRect
Apr 17 Javascript
jQuery实现的多选框多级联动插件
May 02 Javascript
利用函数的惰性载入提高javascript代码执行效率
May 05 Javascript
文本框倒叙输入让输入框的焦点始终在最开始的位置
Sep 01 Javascript
JavaScript中判断变量是数组、函数或是对象类型的方法
Feb 25 Javascript
javascript实现的字符串与十六进制表示字符串相互转换方法
Jul 17 Javascript
浅谈js常用内置方法和对象
Sep 24 Javascript
移动端脚本框架Hammer.js
Dec 15 Javascript
jQuery插件zTree实现获取一级节点数据的方法
Mar 08 Javascript
Vue2(三)实现子菜单展开收缩,带动画效果实现方法
Apr 28 Javascript
小程序实现录音功能
Sep 22 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
收音机怀古---春雷3P7图片欣赏
2021/03/02 无线电
php array_search() 函数使用
2010/04/13 PHP
php添加文章时生成静态HTML文章的实现代码
2013/02/17 PHP
php判断两个浮点数是否相等的方法
2015/03/14 PHP
ThinkPHP框架实现导出excel数据的方法示例【基于PHPExcel】
2018/05/12 PHP
ExtJS GTGrid 简单用户管理
2009/07/01 Javascript
Chrome中模态对话框showModalDialog返回值问题的解决方法
2010/05/25 Javascript
document.documentElement和document.body区别介绍
2013/09/16 Javascript
非常漂亮的JS+CSS图片幻灯切换特效
2013/11/20 Javascript
JS实现div居中示例
2014/04/17 Javascript
Javascript图片上传前的本地预览实例
2014/06/16 Javascript
容易造成JavaScript内存泄露几个方面
2014/09/04 Javascript
jquery实现简单的轮换出现效果实例
2015/07/23 Javascript
微信小程序scroll-view隐藏滚动条的方法详解
2020/03/25 Javascript
js实现简单抽奖功能
2020/11/24 Javascript
[01:44]《为梦想出发》—联想杯DOTA2完美世界全国高校联赛
2015/09/30 DOTA
[06:45]2018DOTA2亚洲邀请赛 4.5 SOLO赛 Sccc vs Maybe
2018/04/06 DOTA
浅谈python类属性的访问、设置和删除方法
2016/07/25 Python
利用Python读取文件的四种不同方法比对
2017/05/18 Python
Python金融数据可视化汇总
2017/11/17 Python
Python 3.7新功能之dataclass装饰器详解
2018/04/21 Python
python字符串替换第一个字符串的方法
2019/06/26 Python
Python: glob匹配文件的操作
2020/12/11 Python
皇家道尔顿官网:Royal Doulton
2017/12/06 全球购物
美国滑板店:Tactics
2020/11/08 全球购物
给老婆的搞笑检讨书
2014/01/12 职场文书
四年级科学教学反思
2014/02/10 职场文书
演讲比赛策划方案
2014/06/11 职场文书
2014个人反腐倡廉思想汇报
2014/09/15 职场文书
小学趣味运动会加油稿
2014/09/25 职场文书
保送生自荐信范文
2015/03/26 职场文书
2015社区爱国卫生工作总结
2015/04/21 职场文书
公司聚餐通知
2015/04/22 职场文书
2015年行风建设工作总结
2015/05/15 职场文书
机械生产实习心得体会
2016/01/22 职场文书
Java详细解析==和equals的区别
2022/04/07 Java/Android