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开发技术大全 第4章 直接量与字符集
Jul 03 Javascript
基于JQuery的多标签实现代码
Sep 19 Javascript
js文件包含的几种方式介绍
Sep 28 Javascript
JavaScript 函数模式详解及示例
Sep 07 Javascript
一个极为简单的requirejs实现方法
Oct 20 Javascript
ionic2 tabs使用 Modal底部tab弹出框
Dec 30 Javascript
浅谈Vuex的状态管理(全家桶)
Nov 04 Javascript
jQuery中each遍历的三种方法实例分析
Sep 07 jQuery
JQuery模拟实现网页中自定义鼠标右键菜单功能
Nov 14 jQuery
JS箭头函数和常规函数之间的区别实例分析【 5 个区别】
May 27 Javascript
Vue自定义全局弹窗组件操作
Aug 11 Javascript
Vue封装Axios请求和拦截器的步骤
Sep 16 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中实现Javascript的escape()函数代码
2010/08/08 PHP
PHP的explode和implode的使用说明
2011/07/17 PHP
Laravel框架中实现使用阿里云ACE缓存服务
2015/02/10 PHP
php封装的表单验证类完整实例
2016/10/19 PHP
YII框架常用技巧总结
2019/04/27 PHP
关于laravel后台模板laravel-admin select框的使用详解
2019/10/03 PHP
javascript中类的定义及其方式(《javascript高级程序设计》学习笔记)
2011/07/04 Javascript
JS中Iframe之间传值的方法
2013/03/11 Javascript
js禁止页面刷新禁止用F5键刷新禁止右键的示例代码
2013/09/23 Javascript
jquery trigger伪造a标签的click事件取代window.open方法
2014/06/23 Javascript
js使用for循环与innerHTML获取选中tr下td值
2014/09/26 Javascript
网页禁用右键菜单和鼠标拖动选择方法小结
2015/02/25 Javascript
angularjs学习笔记之三大模块(modal,controller,view)
2015/09/26 Javascript
JavaScript时间戳与时间日期间相互转换
2017/12/11 Javascript
Vue.js上传图片到阿里云OSS存储的方法示例
2018/12/13 Javascript
vue实现分环境打包步骤(给不同的环境配置相对应的打包命令)
2019/06/04 Javascript
js实现打字小游戏
2019/12/17 Javascript
利用vue3+ts实现管理后台(增删改查)
2020/10/30 Javascript
原生js实现移动小球(碰撞检测)
2020/12/17 Javascript
Python脚本实现格式化css文件
2015/04/08 Python
举例讲解Python中字典的合并值相加与异或对比
2016/06/04 Python
Python PyAutoGUI模块控制鼠标和键盘实现自动化任务详解
2018/09/04 Python
python实现将文件夹下面的不是以py文件结尾的文件都过滤掉的方法
2018/10/21 Python
Python3实现获取图片文字里中文的方法分析
2018/12/13 Python
Python中一个for循环循环多个变量的示例
2019/07/16 Python
MAC平台基于Python Appium环境搭建过程图解
2020/08/13 Python
Python通过format函数格式化显示值
2020/10/17 Python
如何使用 Flask 做一个评论系统
2020/11/27 Python
莫斯科绝对前卫最秘密的商店:SVMoscow
2017/10/23 全球购物
上海某公司.net方向笔试题
2014/09/14 面试题
服装设计专业毕业生推荐信
2013/11/09 职场文书
学习教师敬业奉献模范事迹材料思想汇报
2014/09/19 职场文书
开会通知
2015/04/20 职场文书
2015年全国爱眼日活动方案
2015/05/05 职场文书
简单的辞职信范文(2016最新版)
2015/05/12 职场文书
Python 数据可视化之Matplotlib详解
2021/11/02 Python