`

json转换 eval问题

阅读更多
什么是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实现,以便得到更好的性能和更安全的操作。
详细出处参考:http://www.jb51.net/article/17721.htm
分享到:
评论

相关推荐

    json转换.docx

    首先,可以使用 eval() 函数,该函数可以将 JSON 字符串转换为 JavaScript 对象,例如: ``` var object = eval("(" + jsonTxt + ")"); ``` 其次,可以使用 JSON.parse() 方法,该方法也可以将 JSON 字符串转换为 ...

    json转换(js)

    ### JSON转换在JavaScript中的应用 #### 一、前言 在现代Web开发中,JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,易于人阅读和编写,同时也易于机器解析和生成。JSON数据通常被用来传输服务器...

    巧用eval解析json对象

    `eval()`可以执行一个字符串作为JavaScript代码,因此,当接收到一个JSON字符串时,可以通过`eval()`将其转换为对象: ```javascript let jsonString = '{"name": "John", "age": 30, "city": "New York"}'; let ...

    javascript eval和JSON

    通过本文的介绍,我们可以了解到`eval`函数在处理字符串形式的JavaScript代码方面的强大功能,以及在JSON数据转换过程中的应用。同时,我们也应该注意到在实际项目中避免滥用`eval`的重要性,尤其是在处理用户提交的...

    JSON后台相互转换.docx

    JsonUtil工具类提供了一些常用的JSON转换Java对象和Java对象转换JSON的方法。例如,JsonUtil工具类提供了getObject4JsonString方法,可以将JSON字符串转换为Java对象。 ```java public static Object getObject4...

    字符串转换成json 的三种方式

    在JavaScript编程中,将字符串转换...`eval`和`new Function`虽然在早期被广泛使用,但由于安全问题,现在已经被淘汰。在编写JavaScript代码时,应该优先考虑使用`JSON.parse`,并在必要时提供polyfill以确保向后兼容。

    纯javascript实现json与对象的互相转换项目

    - `JSON.parse()`不会执行JavaScript代码,所以它比直接使用`eval()`更安全。 这个项目对于学习JavaScript深入理解数据结构、字符串操作以及递归处理有很好的实践价值。同时,它也能够帮助开发者更好地理解和掌握...

    字符串转换成json的三种方式

    在IT行业中,字符串转换成JSON(JavaScript Object Notation)是一种常见的操作,特别是在处理API响应、存储数据或交换信息时。本文将详细介绍三种方法,帮助你有效地实现这一转换。首先,让我们了解一下JSON的基本...

    jqeury eval将字符串转换json的方法

    jqeury eval将字符串转换json的方法 jqeury eval将字符串转换json的方法是一个将DataTable转换成字符串的方法。该方法使用了JavaScript的eval函数来将字符串转换成json对象。下面是对该方法的详细解释: 首先,在...

    list集合转换为json对象.doc

    本文将详细介绍如何将`list集合转换为json对象`,以及相关的JSON转换方法。JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,易于人阅读和编写,同时也易于机器解析和生成。在JavaScript中,我们可以...

    JSON2解决JSON未定义

    在JSON2.js中,它通过使用eval()函数和try/catch语句来实现,尽管这种方法存在一定的安全风险,但在旧版IE中这是唯一的可行方案。 - `JSON.stringify()` 方法则是将JavaScript值转换为JSON字符串。它接受三个参数:...

    js下用eval生成JSON对象.docx

    然而,当涉及到从服务器端获取JSON数据并将其转换为JavaScript对象时,`eval()`通常被用来解析这些数据。但是,这种方法存在一定的安全风险,因此在实际开发中,推荐使用更安全的JSON.parse()方法。 在描述中提到,...

    json-lib-2.4 jar 程序文件

    6. **JSONPath支持**:JSON-Lib提供了一种类似XPath的方式来查询JSON数据,通过`JSONArray jsonArray = JSONPath.eval(jsonObject, "$.path");`可以获取指定路径下的JSON元素。 7. **性能优化**:虽然JSON-Lib功能...

    json字符串和js对象之间的转换

    尽管`eval()` 可以解析JSON字符串并将其转化为JavaScript对象,但由于安全性和性能问题,不推荐使用。示例: ```javascript var jsonString = '{"name":"John", "age":30, "city":"New York"}'; var jsonObject = ...

    javascript中eval解析JSON字符串.docx

    尽管`eval()`可以用于解析JSON字符串,但它存在一些明显的缺点和安全问题: 1. **安全性**:直接执行字符串中的任意代码是非常危险的,因为这可能导致XSS攻击。 2. **性能**:`eval()`的执行速度通常比原生的`JSON....

    javascript中eval解析JSON字符串

    JSON.parse()能够将JSON格式的字符串转换成JavaScript对象。 JSON字符串是JavaScript对象的字符串化表示,如果直接使用eval来解析一个JSON字符串,可能会因为JSON字符串不是有效的JavaScript语句而导致语法错误。...

    javascript json字符串到json对象转义问题

    总的来说,当处理JSON字符串时,确保字符串中的特殊字符(如双引号)已经正确转义,使用`JSON.parse()`进行转换,如果遇到兼容性问题,可以使用`eval()`作为备选方案。同时,对于全局替换需求,记得使用正则表达式和...

    jQuery方法扩展:type, toJSON, evalJSON

    然而,由于`eval`在安全性和性能上的问题,`evalJSON`现在已被弃用。推荐使用JavaScript内置的`JSON.parse`方法来替代: ```javascript var jsonString = '{"name":"John","age":30}'; var parsedData = $.evalJSON...

    JavaScript的eval JSON object问题

    标题:“JavaScript的eval JSON object问题”所指的知识点主要包括以下几个方面: 1. AJAX技术及其数据交互:AJAX(Asynchronous JavaScript and XML)是一种在无需重新加载整个页面的情况下,能够更新部分网页的...

    eval 加密和解密

    在JavaScript中,`eval`通常用于处理JSON对象,因为JSON.stringify()方法会将JavaScript对象转换成一个JSON格式的字符串,而JSON.parse()则能将这个字符串解析回JavaScript对象。但出于安全考虑,直接使用`eval`解析...

Global site tag (gtag.js) - Google Analytics