IE8 原生JSON支持


Posted in Javascript onApril 13, 2009

这种新的原生JSON功能能够使Internet Explorer 8对现有的AJAX应用程序运行得更加快速和安全。

什么是JSON?

大多数开发者不是只进行AJAX程序程序开发的,我这里先介绍一点背景知识。JSON是一种简单的、人能够阅读的数据交换格式,在AJAX程序中,当服务器与web程序之间传输数据时,通常采用这种格式。

举例来说,假如你从收藏的web邮件中选择一个联系人名称,以便能够看到该联系人信息。服务器向web程序(运行在浏览器中)发送的数据流可能是下面的样子:

     {
          "firstName": "cyra",
           "lastName": "richardson",
           "address": {
                "streetAddress": "1 Microsoft way",
                 "city": "Redmond",
                 "state": "WA",
                 "postalCode": 98052
          },

           "phoneNumbers": [
                "425-777-7777",  
                 "206-777-7777"
           ]
     }

值得庆幸的是,这种格式与JavaScript的语法完全兼容。当今的很多程序使用Javascript的eval()函数将这种得到的数据转换成 Javascript对象。使用eval()是不安全的,并且耗费资源。eval()将这个字符串解析为Jscript表达式,并且执行。如果传递给 eval()的字符串被篡改过,它就可能含有我们不期望的数据,甚至是别人的代码,这样就注入到了你的web程序中。

现在,有很多采用 Javascript编写的库,用来更加安全地解析不受信任的JSON数据。有些使用Jscript编写的解析器(http: //www.json.org/json_parser.js)对数据进行了严格的验证,有些库,像json2,js(http: //www.json.org/json2.js),采用正则表达式对输入的字符串进行全面的检查,然后使用eval()快速解析。理想的解决方案是一种原生实现方法,避免应用程序遭受代码注入,运行很快,并且随处都能使用。

IE8 Jscript中原生JSON

IE8 的Jscript引擎已经有了JSON完全的原生实现,在保持与ES3.1提案草案(Proposal  Working Draft,地址http://wiki.ecmascript.org/doku.php?id=es3.1: es3.1_proposal_working_draft)中所描述的JSON支持的兼容性的同时,极大地提高了序列化、反序列化的速度,并且提高解析不信任数据的安全性。

API

我们定义了一个新的内置对象“JSON”,这个对象可被修改或者重写。看上去很像math或者其他内置的全局对象。除了JSON对象之外,toJSON()这些特定的函数也添加到了Date、Number、String和 boolean对象的原型上。JSON对象有两个方法:parse()和stringify()。

例如:

var jsObjString = "{\"memberNull\" : null, \"memberNum\" : 3, \"memberStr\" : \"StringJSON\", \"memberBool\" : true , \"memberObj\" : { \"mnum\" : 1, \"mbool\" : false}, \"memberX\" : {}, \"memberArray\" : [33, \"StringTst\",null,{}]";
var jsObjStringParsed = JSON.parse(jsObjString);
var jsObjStringBack = JSON.stringify(jsObjStringParsed);

这个由parse()方法产生、又通过stringify()方法序列化回去的对象与下面的对象是完全一样的:

var jsObjStringParsed =
{
     "memberNull" : null,
     "memberNum" : 3,
     "memberStr" : "StringJSON",
     "memberBool" : true ,
     "memberObj" :
     {
                 "mnum" : 1,
                 "mbool" : false
    },
     "memberX" : {},
     "memberArray" :  
     [
                 33,
                 "StringTst",
                 null,
                 {}
     ]
};

JSON.parse(source, reviver)

JSON.parse方法执行反序列化,它采用JSON格式的字符串(由参数source指定),产生Jscript对象或者数组。

可选参数revive是一个用户自定义函数,用来计入解析的变化。结果对象或者数组递归遍历,reviver函数用在每一个成员上,每个成员值被 reviver的返回值所替代。如果reviver返回null,则对象成员被删除。对reviver的遍历和调用是按后序遍历完成的。也就是说:对象的所有成员被“revived”之后,整个对象也就“revived”了。

reviver主要用来识别类似ISO这样的字符串,将它们转成 Date对象。到目前为止,JSON格式(http://www.json.org/)对Date对象来说,是不能来回转换的,这是因为没有 Jscript的标准Date文字量。ES3.1草案(http://wiki.ecmascript.org/doku.php?id=es3.1: es3.1_proposal_working_draft)包含了一个如何使用reviver函数解决这个问题的例子。

JSON.stringify(value, replacer, space)

这个是序列化方法。它以由value参数指定的对象或者数组为参数,生成JSON格式的字符串。对象或者数组递归访问,序列化成特定的JSON格式。如果 value参数有toJSON()方法,那么这个方法就起第一个过滤器的作用,原始的value被value.toJSON(key)替代,最终的值被序列化。参数key是一个字符串,当类似(key:value)这样的对象被序列化时,key是成员的名字。对根对象来说,key是空字符串。

Date.prototype.toJSON()生成一个无需转义的字符串,是真正的序列化器,因为stringify()会返回最原始、没有任何变化的字符串。Date对象通过toJSON()方法进行序列化。

Number.prototype.toJSON ()、String.prototype.toJSON()、 Boolean.prototype.toJSON()函数返回ValueOf()。他们用来进行对象的正确序列化,像“ var num = new Number(3.14);”这样的对象。

可选的replacer参数起过滤器的作用,递归使用。它可以是个函数,也可以是个数组。如果 replacer是一个函数,那么对每个对象成员key:value都调用replacer(key,value)。至于根对象,调用replacer ("",value)。如果replacer是个数组,则必须是个数组字符串。数组的元素就是要进行序列化成员的名字。序列化的顺序按照数组中的名字顺序。在序列化数组时,数组replacer是被忽略的。

可选的参数space是关于如何格式化输出文字的,如果该参数省略,则输出文字没有任何额外的空格。如果它是一个数字,它指定的是每个级别缩进的空格数。如果它是一个字符(比如"\t"或者“ ”),它就以这些字符缩进每一个级别的字符。

对现有的网页有何影响?

ES3.1 JSON提案是被流行的json2.js所使用的主要因素。我们也采用JSON这个名字。全局对象JSON能够被重写。然而,它不再是一个未定义的对象。这与通过在脚本语言中引入new关键字是相同的。采用一个名字偶尔会影响现有的代码。使用json2.js的页面不太可能会受影响。除了极少数的例外,所有这些页面都将会继续正常工作,只能是运行得更快。

那些自己实现的JSON对象定义的页面可能会受到影响,尤其是使用类似“if(!this.JSON) { JSON=…}”这种模式定义的JSON对象。有两种主要的方法可以解决这个问题:

1,将现有代码迁移,使用原生JSON对象
如果自己的JSON实现是基于json2.js的某种版本的,迁移起来就很简单。

2,决定不使用原生JSON支持,继续使用自己现有的JSON对象
这可以通过重命名或者重写JSON名字实现。重命名意味着要将所有使用JSON名字的代码修改成类似“MyJSON”这样的名字。重写意味着确保自己的 JSON定义重写所有使用默认原生JSON定义的代码。大多数情况下,只需移除条件“if(!this.JSON)”就可以了。

考虑到3.1标准的影响,使用JSON这个名字与我们通过定义好的接口进行互操作的愿望是一致的。

关于原生JSON,要谈论的事情还有很多。解析器不是基于eval() 的,是一个独立的实现。它与JSON支持(http://wiki.ecmascript.org/doku.php?id=es3.1: json_support)提供的引用解析器是等同的。它也是和http://www.json.org/json_parser.js一样安全的,并且运行速度要快很多。所以,如果你使用eval(),或自己的JSON库,请检查一下IE8中原生JSON实现,以便得到更好的性能和更安全的操作。

Javascript 相关文章推荐
JS获取页面窗口大小的代码解读
Dec 01 Javascript
jQuery如何实现点击页面获得当前点击元素的id或其他信息
Jan 09 Javascript
Javascript函数式编程语言
Oct 11 Javascript
JavaScript统计网站访问次数的实现代码
Nov 18 Javascript
jquery插件EasyUI中form表单提交实例分享
Jan 11 Javascript
getElementById().innerHTML与getElementById().value的区别
Oct 27 Javascript
JS访问DOM节点方法详解
Nov 29 Javascript
详解小程序之简单登录注册表单验证
May 13 Javascript
Vue项目打包压缩的实现(让页面更快响应)
Mar 10 Javascript
vue调用微信JSDK 扫一扫,相册等需要注意的事项
Jan 03 Vue.js
详解基于element的区间选择组件校验(交易金额)
Jan 07 Javascript
javascript进阶篇深拷贝实现的四种方式
Jul 07 Javascript
由document.body和document.documentElement想到的
Apr 13 #Javascript
js cookies 常见网页木马挂马代码 24小时只加载一次
Apr 13 #Javascript
javascript removeChild 使用注意事项
Apr 11 #Javascript
Firefox window.close()的使用注意事项
Apr 11 #Javascript
javascript html 静态页面传参数
Apr 10 #Javascript
js 判断浏览器类型 去全角、半角空格 自动关闭当前窗口
Apr 10 #Javascript
javascript 原型模式实现OOP的再研究
Apr 09 #Javascript
You might like
VIM中设置php自动缩进为4个空格的方法详解
2013/06/14 PHP
PHP中串行化用法示例
2016/11/16 PHP
PHP使用Nginx实现反向代理
2017/09/20 PHP
从sohu弄下来的flash中展示图片的代码
2007/04/27 Javascript
JavaScript eval() 函数介绍及应用示例
2014/07/29 Javascript
Node.js实现批量去除BOM文件头
2014/12/20 Javascript
JavaScript获取网页中第一个链接ID的方法
2015/04/03 Javascript
jQuery插件制作的实例教程
2016/05/16 Javascript
利用angular.copy取消变量的双向绑定与解析
2016/11/25 Javascript
jQuery插件zTree实现更新根节点中第i个节点名称的方法示例
2017/03/08 Javascript
微信小程序图片自适应支持多图实例详解
2017/06/21 Javascript
react路由配置方式详解
2017/08/07 Javascript
小程序实现页面顶部选项卡效果
2018/11/06 Javascript
Vue2.0使用嵌套路由实现页面内容切换/公用一级菜单控制页面内容切换(推荐)
2019/05/08 Javascript
一文了解vue-router之hash模式和history模式
2019/05/31 Javascript
vue-iview动态新增和删除的方法
2020/06/17 Javascript
如何基于jQuery实现五角星评分
2020/09/02 jQuery
python遍历文件夹并删除特定格式文件的示例
2014/03/05 Python
在Python的Flask框架中实现单元测试的教程
2015/04/20 Python
python函数中return后的语句一定不会执行吗?
2017/07/06 Python
pygame 精灵的行走及二段跳的实现方法(必看篇)
2017/07/10 Python
Python远程视频监控程序的实例代码
2019/05/05 Python
python爬虫爬取笔趣网小说网站过程图解
2019/11/18 Python
Python实现树莓派摄像头持续录像并传送到主机的步骤
2020/11/30 Python
一款利用纯css3实现的超炫3D表单的实例教程
2014/12/01 HTML / CSS
详解css3中dispaly的Grid布局与Flex布局
2020/09/11 HTML / CSS
贝嫂喜欢的婴儿品牌,个性化的婴儿礼物:My 1st Years
2017/11/19 全球购物
Hashtable 添加内容的方式有哪几种,有什么区别?
2012/04/08 面试题
优秀干部获奖感言
2014/01/31 职场文书
《苏珊的帽子》教学反思
2014/04/07 职场文书
副科竞争上岗演讲稿
2014/05/12 职场文书
音乐教师个人总结
2015/02/06 职场文书
2016年教师节感恩寄语
2015/12/04 职场文书
假期读书倡议书3篇
2019/08/19 职场文书
导游词之云南丽江-泸沽湖
2019/09/26 职场文书
Python基础之进程详解
2021/05/21 Python