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代码
Mar 06 Javascript
理解Javascript_15_作用域分配与变量访问规则,再送个闭包
Oct 20 Javascript
js动态加载以及确定加载完成的代码
Jul 31 Javascript
javascript游戏开发之《三国志曹操传》零部件开发(四)用地图块拼成大地图
Jan 23 Javascript
JavaScript常用验证函数实例汇总
Nov 25 Javascript
JavaScript实现点击按钮切换网页背景色的方法
Oct 17 Javascript
Javascript实现的StopWatch功能示例
Jun 13 Javascript
vue项目中,main.js,App.vue,index.html的调用方法
Sep 20 Javascript
小程序实现单选多选功能
Nov 04 Javascript
vue子组件改变父组件传递的prop值通过sync实现数据双向绑定(DEMO)
Feb 01 Javascript
Openlayers学习之地图比例尺控件
Sep 28 Javascript
Vue实现tab导航栏并支持左右滑动功能
Jun 28 Vue.js
由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 MYSQL中插入当前时间
2008/04/06 PHP
php 遍历显示文件夹下所有目录、所有文件的函数,没有分页的代码
2008/11/14 PHP
PHP去掉json字符串中的反斜杠\及去掉双引号前的反斜杠
2015/09/30 PHP
php操作redis命令及代码实例大全
2020/11/19 PHP
jQuery 核心函数以及jQuery对象
2010/03/23 Javascript
jQuery DOM删除节点操作指南
2015/03/03 Javascript
JavaScript中数据结构与算法(二):队列
2015/06/19 Javascript
充分发挥Node.js程序性能的一些方法介绍
2015/06/23 Javascript
SWFObject基本用法实例分析
2015/07/20 Javascript
基于Bootstrap使用jQuery实现输入框组input-group的添加与删除
2016/05/03 Javascript
Markdown+Bootstrap图片自适应属性详解
2016/05/21 Javascript
Bootstrap框架安装使用详解
2017/01/21 Javascript
nodejs mysql 实现分页的方法
2017/06/06 NodeJs
JavaScript代码执行的先后顺序问题
2017/10/29 Javascript
AngularJS实时获取并显示密码的方法
2018/02/06 Javascript
vue.js使用v-model指令实现的数据双向绑定功能示例
2018/05/22 Javascript
详解使用 Node.js 开发简单的脚手架工具
2018/06/08 Javascript
关于layui 下拉列表的change事件详解
2019/09/20 Javascript
解决antd的Form组件setFieldsValue的警告问题
2020/10/29 Javascript
[00:30]明星选手化身超级英雄!2018DOTA2亚洲邀请赛全明星赛来临!
2018/04/06 DOTA
python将MongoDB里的ObjectId转换为时间戳的方法
2015/03/13 Python
scikit-learn线性回归,多元回归,多项式回归的实现
2019/08/29 Python
python 模拟贷款卡号生成规则过程解析
2019/08/30 Python
python mysql自增字段AUTO_INCREMENT值的修改方式
2020/05/18 Python
python 爬虫如何正确的使用cookie
2020/10/27 Python
python+selenium爬取微博热搜存入Mysql的实现方法
2021/01/27 Python
CSS3中:nth-child和:nth-of-type的区别深入理解
2014/03/10 HTML / CSS
Ever New加拿大官网:彰显女性美
2018/10/05 全球购物
中职应届生会计求职信
2013/10/23 职场文书
迎元旦广播稿
2014/02/22 职场文书
2014年计划生育协会工作总结
2014/11/14 职场文书
毕业生班级鉴定评语
2015/01/04 职场文书
家庭贫困证明
2015/06/16 职场文书
诺贝尔奖获得者名言100句:句句启人心智,值永久收藏
2019/08/09 职场文书
Java 定时任务技术趋势简介
2022/05/04 Java/Android
Python使用永中文档转换服务
2022/05/06 Python