`

function was not called----parsererror问题

 
阅读更多

问题来源:在ajax跨域调用网上找的一个获取手机号码归属地的接口,但是返回的数据不是严格标准的json,是那种比较老的格式,引起了jquery对于json解析的问题,这是两篇对于解决这个问题有用的贴子,先存着

    function was not called----parsererror

jQuery1.4.2与老版本json格式兼容的解决方法


原来使用jQuery1.3.2编写的代码,更换到1.4.2后,使用jQuery.ajax()加载的json文件,不能正常加载。(使用jQuery.getJSON()也一样)
原json文件内容为:
{
label: 'Europe (EU27)',
data: [[1999, 3.0], [2000, 3.9], [2001, 2.0], [2002, 1.2], [2003, 1.3], [2004, 2.5], [2005, 2.0], [2006, 3.1], [2007, 2.9], [2008, 0.9]]
}
解决方法一:
改成标准的json格式,要求对字符串都使用""限定,修改后的内容为:
{
"label": "Europe (EU27)",
"data": [[1999, 3.0], [2000, 3.9], [2001, 2.0], [2002, 1.2], [2003, 1.3], [2004, 2.5], [2005, 2.0], [2006, 3.1], [2007, 2.9], [2008, 0.9]]
}
这样就可以正常加载了。
解决方法二:
在jQuery-1.4.2.js中找到"parseJSON: function",可发现有如下代码:
复制代码 代码如下:

// Logic borrowed from http://json.org/json2.js
if ( /^[\],:{}\s]*$/.test(data.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, "@")
.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, "]")
.replace(/(?:^|:|,)(?:\s*\[)+/g, "")) ) {
// Try to use the native JSON parser first
return window.JSON && window.JSON.parse ?
window.JSON.parse( data ) :
(new Function("return " + data))();
} else {
jQuery.error( "Invalid JSON: " + data );
}

在httpData: function中用到了parseJSON函数:
复制代码 代码如下:

// Get the JavaScript object, if JSON is used.
if ( type === "json" || !type && ct.indexOf("json") >= 0 ) {
data = jQuery.parseJSON( data );

在jQuery1.3.2中,没有parseJSON这个方法,而是直接使用下面的代码。
复制代码 代码如下:

// Get the JavaScript object, if JSON is used.
if ( type == "json" )
data = window["eval"]("(" + data + ")");

替换成原来1.3.2的代码就可以了。
下面是其它网友的一些补充:
jquery1.4.2版本在性能上又提升了一倍,但有一个令人头痛的事就是$.getJSON函数,原先使用旧版本的JSON数据如果写得不标准,使用这个版本就无法正常获取JSON数据了
例如:
JSON不标准的写法
复制代码 代码如下:

{Err:1,errmsg:'无效ID值!请从正确表单页提交!'}

jquery1.4.x以下旧版本是能正常获取的,如果你的程序开发时用的是这类格式,那就头痛了,因为如果升级JQUERY到新版本,这种格式是读取不了的
JSON标准的写法,各种版本都能正常获取
复制代码 代码如下:

{"Err":1,"errmsg":"无效ID值!请从正确表单页提交!"}

这是因为jquery1.4.X版本里使用了native json parser,对json格式有严格的要求
如果你不想修改程序的JSON数据,还有什么方法能让旧新据适合用在新版本上呢?
方法是有的,只要恢复回旧版本的JSON处理函数就可以了,修改方法如下:
jq1.4.x Regular 版本修改
打开jquery-1.4.x.js文件,找到下面代码:
data = jQuery.parseJSON( data );
修改为以下代码:
data = window["eval"]("(" + data + ")");
jq1.4.x Minified 版本修改
打开jquery-1.4.x.min.js文件,找到下面代码:
a=c.parseJSON(a);
修改为以下代码:
a= window["eval"]("(" + a+ ")");
试试你的程序吧,呵呵,$.getJSON是不是正常了?
当然,如果你有能力写正则的话,可以修改新版本的parseJSON函数里JSON处理正则

================================分割线===================================
    解析JSON和XML:jQuery.parseJSON( data )、jQuery.parseXML( data )

    1.jQuery.parseJSON( data )

    方法jQuery.parseJSON( data )接受一个格式良好的JSON字符串,返回解析后的JavaScript对象。如果传入残缺的JSON字符串可能导致程序抛出异常;如果不传入参数,或者传入空字符串、null、undefined,则返回null。

    如果浏览器提供了原生方法JSON.parse(),则使用该方法解析JSON字符串;否则使用
    ( new Function( "return"+ data ) )()解析JSON字符串。

    方法jQuery.parseJSON( data )的相关代码如下所示:
    555      parseJSON: function( data ) {
    556         if ( typeof data !== "string" || !data ) {
    557             return null;
    558         }
    559
    560         // Make sure leading/trailing whitespace is removed (IE can't handle it)
    561         data = jQuery.trim( data );
    562
    563         // Attempt to parse using the native JSON parser first
    564         if ( window.JSON && window.JSON.parse ) {
    565             return window.JSON.parse( data );
    566         }
    567
    568         // Make sure the incoming data is actual JSON
    569         // Logic borrowed from http:// json.org/json2.js
    570         if ( rvalidchars.test( data.replace( rvalidescape, "@" )
    571             .replace( rvalidtokens, "]" )
    572             .replace( rvalidbraces, "")) ) {
    573
    574             return ( new Function( "return " + data ) )();
    575
    576         }
    577         jQuery.error( "Invalid JSON: " + data );
    578      },

    第556~561行:对于非法参数一律返回null。如果参数data不是字符串,或者可以转换为false,则返回null。

    第561行:移除开头和末尾的空白符。在IE 6/7中,如果不移除就不能正确的解析,例如:
    typeof ( new Function( 'return ' + '\n{}' ) )();
    // 返回"undefined"

    第564~566行:尝试使用原生方法JSON.parse()解析JSON字符串,并返回。

    JSON对象含有两个方法:JSON.parse()和JSON.stringify(),用于JSON字符串和JavaScript对象之间的相互转换。下面是它们的语法和使用示例。

    JSON.parse()解析JSON字符串为 JSON对象,其语法如下:
    JSON.parse(text[, reviver])
    // text 待解析为 JSON 对象的字符串
    // reviver 可选。在返回解析结果前,对解析结果中的属性值进行修改
    JSON.parse()的使用示例如下所示:
    JSON.parse( '{ "abc": 123 }' );
    // {"abc": 123 }

    JSON.parse( '{ "abc": 123 }', function( key, value ){
       if( key === '' ) return value;
       return value * 2;
    } );
    // {"abc": 246 }

    JSON.stringify()转换JSON对象为JSON字符串,其语法如下:
    JSON.stringify( value[, replacer [, space]] )
    // value 待转换为 JSON 字符串的对象
    // replacer 可选。如果 replacer 是函数,转换前先执行 replacer 改变属性值,如果函数 replacer 返回 undefined,则对应的属性不会出现在结果中;如果 replacer 是数组,指定最终字符串中包含的属性集合,不在数组 replacer 中的属性不会出现在结果中
    // space 增加转换后的 JSON 字符串的可读性

    JSON.stringify()的使用示例如下所示:
    JSON.stringify( { a: 1, b: 2 } );
    // '{"a":1,"b":2}'

    JSON.stringify( { a: 1, b: 2 }, function( key, value ){
       if( key === '' ) return value;
       if( key === 'a' ) return value * 10;
       if( key === 'b' ) return undefined;
       return value;
    } );
    // '{"a":10}'

    JSON.stringify( { a: 1, b: 2 }, ['b'] );
    // '{"b":2}'

    JSON.stringify( { a: 1, b: 2 }, null, 4 );
    // '{\n    "a": 1,\n    "b": 2\n}'

    JSON对象、JSON.parse()、JSON.stringify()在ECMAScript 5中被标准化,IE 8以下的浏览器不支持。关于JSON规范和浏览器实现的更多信息请访问以下地址:

    http://json.org/json-zh.html

    http://www.ecma-international.org/publications/standards/Ecma-262.htm(ECMAScript 5第15.12节)

    https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/JSON
    下面回到对方法jQuery.parseJSON()的分析中来。

    第570~576行:在不支持JSON.parse()的浏览器中,先检查字符串是否合法,如何合法,才会执行( new Function("return"+ data) )()并返回执行结果。检查字符串是否合法的正则和逻辑来自开源JSON解析库json2.js(https://github.com/douglascrockford/JSON-js),检测过程分为4步,用到了4个正则表达式:rvalidchars、rvalidescape、rvalidtokens、rvalidbraces,相关代码如下:
     53     // JSON RegExp
     54     rvalidchars = /^[\],:{}\s]*$/,
     55     rvalidescape = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,
     56     rvalidtokens = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,
     57     rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g,

    570         if ( rvalidchars.test( data.replace( rvalidescape, "@" )
    571             .replace( rvalidtokens, "]" )
    572             .replace( rvalidbraces, "")) ) {

    第54~57行:正则rvalidescape用于匹配转义字符;正则rvalidtokens用于匹配有效值(字符串、true、false、null、数值);正则rvalidbraces用于匹配正确的左方括号“[”;正则rvalidchars用于检查字符串是否只含有指定的字符(“]”、“,”、“:”、“{”、“}”、“\s”)。

    第570~572行:先利用正则rvalidescape把转义字符替换为“@”,为进行下一步替换做准备;再利用正则rvalidtokens把字符串、true、false、null、数值替换为“]”;然后利用rvalidbraces删除正确的左方括号;最后检查剩余字符是否只包含“]”、“,”、“:”、“{”、“}”、“\s”,如果只包含这些字符,那么认为JSON字符串是合法的。
    第574行:通过构造函数Function()创建函数对象,然后执行。构造函数Function()的语法如下:
    new Function( arguments_names..., body)
    // 参见arguments_names...:任意多个字符串参数,每个字符串命名一个或多个要创建的 Function 对象的参数
    // 参见body:一个字符串,指定函数的主体,可以含有任意多条 JavaScript 语句,这些语句之间用分号隔开,可以给该构造函数引用前面的参数设置的任何参数名
    // 返回新创建的 Function 对象。调用该函数,将执行 body 指定的 JavaScript 代码
    第577行:如果浏览器不支持JSON.parse(),并且JSON字符串不合法,则在最后抛出一个异常。



分享到:
评论

相关推荐

    FlexGraphics_V_1.79_D4-XE10.2_Downloadly.ir

    connector's end point moving, the link is breaks if the move was not on one of the flex-controls connection points. Contain False as default. - ADD Added ControlDocRect parameter in event ...

    acpi控制笔记本风扇转速

    Descriptor field names where an "object does not exist" error could be incorrectly generated if the parent ResourceTemplate pathname places the template within a different namespace scope than the ...

    EurekaLog_7.5.0.0_Enterprise

    1)..Important: Installation layout was changed. All packages now have version suffix (e.g. EurekaLogCore240.bpl). No files are copied to \bin folder of IDE. Run-time package (EurekaLogCore) is copied ...

    au3反编译源码

    If you decompiled a file that was obfuscated all variable and function got lost. Is 'Function Renamer' to transfer the function names from one simulare file to your decompiled au3-file. A ...

    Delphi7.1 Update

    BOLD FOR DELPHI * VERIFYING THAT THE UPDATE WAS SUCCESSFUL * FILES INSTALLED BY THIS UPDATE =======================================================INSTALLING THIS UPDATE* This update can not be ...

Global site tag (gtag.js) - Google Analytics