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 相关文章推荐
java与javascript之间json格式数据互转介绍
Oct 29 Javascript
javascript的数组和常用函数详解
May 09 Javascript
JavaScript 事件绑定及深入
Apr 13 Javascript
jQuery插件实现多级联动菜单效果
Dec 01 Javascript
javascript实现自动填写表单实例简析
Dec 02 Javascript
关于在vue-cli中使用微信自动登录和分享的实例
Jun 22 Javascript
JS实现给json数组动态赋值的方法示例
Mar 19 Javascript
js使用xml数据载体实现城市省份二级联动效果
Nov 08 Javascript
微信小程序CSS3动画下拉菜单效果
Nov 04 Javascript
javascript操作元素的常见方法小结
Nov 13 Javascript
JavaScript设计模式--桥梁模式引入操作实例分析
May 23 Javascript
vue渲染方式render和template的区别
Jun 05 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
Search File Contents PHP 搜索目录文本内容的代码
2010/02/21 PHP
PHP curl伪造IP地址和header信息代码实例
2015/04/27 PHP
ThinkPHP静态缓存简单配置和使用方法详解
2016/03/23 PHP
thinkPHP框架中执行事务的方法示例
2018/05/31 PHP
转换json格式的日期为Javascript对象的函数
2010/07/13 Javascript
GridView中获取被点击行中的DropDownList和TextBox中的值
2013/07/18 Javascript
jquery操作HTML5 的data-*的用法实例分享
2014/08/17 Javascript
详解nodejs 文本操作模块-fs模块(四)
2016/12/22 NodeJs
JavaScript中的call和apply的用途以及区别
2017/01/11 Javascript
详解Angular中的自定义服务Service、Provider以及Factory
2017/04/22 Javascript
详解vue静态资源打包中的坑与解决方案
2018/02/05 Javascript
js中apply和Math.max()函数的问题及区别介绍
2018/03/27 Javascript
微信小程序自定义键盘 内部虚拟支付
2018/12/20 Javascript
jQuery实现经典的网页3D轮播图封装功能【附源码下载】
2019/02/15 jQuery
点击按钮弹出模态框的一系列操作代码实例
2019/03/29 Javascript
jquery更改元素属性attr()方法操作示例
2020/05/22 jQuery
python转换摩斯密码示例
2014/02/16 Python
python通过openpyxl生成Excel文件的方法
2015/05/12 Python
Python写入数据到MP3文件中的方法
2015/07/10 Python
python在非root权限下的安装方法
2018/01/23 Python
python 判断文件还是文件夹的简单实例
2019/06/10 Python
python:动态路由的Flask程序代码
2019/11/22 Python
python新手学习使用库
2020/06/11 Python
深入浅析pycharm中 Make available to all projects的含义
2020/09/15 Python
python判断all函数输出结果是否为true的方法
2020/12/03 Python
全球性的在线购物网站:Zapals
2017/03/22 全球购物
微软美国官方网站:Microsoft美国
2018/05/10 全球购物
法国一家多品牌成衣精品中/高档商店:Graduate Store
2019/08/28 全球购物
现金出纳岗位职责
2014/03/15 职场文书
《第一次抱母亲》教学反思
2014/04/16 职场文书
党委班子剖析材料
2014/08/21 职场文书
优秀护士事迹材料
2014/12/25 职场文书
捐书活动倡议书
2015/04/27 职场文书
装修安全责任协议书
2016/03/22 职场文书
使用RedisTemplat实现简单的分布式锁
2021/11/20 Redis
python通过新建环境安装tfx的问题
2022/05/20 Python