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 相关文章推荐
javascript 面向对象全新理练之继承与多态
Dec 03 Javascript
浅谈javascript的原型继承
Jul 25 Javascript
javascript中字符串的定义示例代码
Dec 19 Javascript
表单提交前触发函数返回true表单才会提交
Mar 11 Javascript
ie8模式下click无反应点击option无反应的解决方法
Oct 11 Javascript
javascript实现点击按钮弹出一个可关闭层窗口同时网页背景变灰的方法
May 13 Javascript
js判断子窗体是否关闭的方法
Aug 11 Javascript
基于Bootstrap实现图片轮播效果
May 22 Javascript
JavaScript实现DOM对象选择器
Sep 24 Javascript
jQuery日程管理插件fullcalendar使用详解
Jan 07 Javascript
Mac中安装nvm的教程分享
Dec 11 Javascript
浅谈开发eslint规则
Oct 01 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
PHP中file_exists函数不支持中文名的解决方法
2014/07/26 PHP
PHP删除二维数组中相同元素及数组重复值的方法示例
2017/05/05 PHP
jquery json 实例代码
2010/12/02 Javascript
JavaScript程序员应该知道的45个实用技巧
2014/03/04 Javascript
jQuery 获取、设置HTML或TEXT内容的两种方法
2014/05/23 Javascript
jQuery结合CSS制作漂亮的select下拉菜单
2015/05/03 Javascript
JavaScript节点及列表操作实例小结
2015/08/05 Javascript
js实现点击切换TAB标签实例
2015/08/21 Javascript
基于jQuery实现的QQ表情插件
2015/08/25 Javascript
基于JavaScript实现TAB标签效果
2016/01/12 Javascript
浅谈时钟的生成(js手写简洁代码)
2016/08/20 Javascript
AngularJS  双向数据绑定详解简单实例
2016/10/20 Javascript
基于JQuery及AJAX实现名人名言随机生成器
2017/02/10 Javascript
原生JS实现垂直手风琴效果
2017/02/19 Javascript
webpack 单独打包指定JS文件的方法
2018/02/22 Javascript
webpack file-loader和url-loader的区别
2019/01/15 Javascript
Python找出9个连续的空闲端口
2016/02/01 Python
Python多进程并发与多线程并发编程实例总结
2018/02/08 Python
python实现AES加密与解密
2019/03/28 Python
详解python播放音频的三种方法
2019/09/23 Python
python如何实现不用装饰器实现登陆器小程序
2019/12/14 Python
解决Python命令行下退格,删除,方向键乱码(亲测有效)
2020/01/16 Python
pytorch 查看cuda 版本方式
2020/06/23 Python
pandas 按日期范围筛选数据的实现
2021/02/20 Python
html+css实现自定义图片上传按钮功能
2019/09/04 HTML / CSS
使用canvas绘制超炫时钟
2014/12/17 HTML / CSS
上学迟到的检讨书
2014/01/11 职场文书
创业大赛策划书
2014/03/01 职场文书
大学专科求职信
2014/07/02 职场文书
化学专业大学生职业生涯规划范文
2014/09/13 职场文书
党的群众路线专项整治方案
2014/11/03 职场文书
2014年教育教学工作总结
2014/11/13 职场文书
班主任自我评价范文
2015/03/11 职场文书
建国大业观后感
2015/06/01 职场文书
普希金诗歌赏析(6首)
2019/08/22 职场文书
SpringBoot+VUE实现数据表格的实战
2021/08/02 Java/Android