一尘不染

IE8本机JSON.parse错误导致堆栈溢出

json

TL; DR: 将任何非内置函数添加到Array.prototype AND
Function.prototype将导致IE8本机JSON解析器在解析包含数组的任何JSON时发生堆栈溢出,但仅当您还传递了reviver函数时放入JSON.parse()。

最初这是一个问题,但我回答了我自己的原始问题,所以现在我要问:有人能想到此IE8错误的解决方法,该方法不涉及消除所有修改Array.prototype和Function的JS库。
。原型?

原始问题:

我有大约13k的JSON数据要解析。数据的结构是一个具有单个值的对象,该值是一个嵌套数组。

{ 'value':[[ stuff ], [ more stuff], [ etc ]] }

我正在使用json2.js,它在可用时会遵循浏览器的本地JSON.parse。我将reviver函数传递给JSON.parse以正确处理日期。当IE8处于IE7仿真模式(导致它使用基于脚本的json2.js解析器)时,一切正常。当IE8处于IE8模式(导致它使用浏览器本地JSON解析器)时,它会爆炸并显示“堆栈空间不足”错误。Firefox和Chrome当然可以与它们的浏览器本地JSON解析器配合使用。

我将其范围缩小到:如果我什至不做任何事情都将reviver函数传递给JSON.parse,则IE8本机解析器将导致堆栈溢出。如果我没有传递任何回复函数,则IE8本机解析器可以正常工作,除非它无法正确解析日期。

// no error:
JSON.parse(stuff);

// "out of stack space" error:
JSON.parse(stuff, function(key, val) { return val; });

我将使用JSON数据,以查看较少的数据或较少的数据嵌套可以避免该错误,但是我想知道是否有人以前见过此方法,或是否有其他建议的解决方法。IE8已经足够慢了,由于这个错误,禁用该浏览器的本机JSON将很可惜。

更新:在其他情况下,使用不同的JSON数据,当我将IE8本机解析器与齐磊函数一起使用时,出现了JavaScript错误“ $
lineinfo未定义”,如果不使用齐磊函数,也没有错误。字符串“ $ lineinfo”在我的任何源代码中都没有出现。

更新2:实际上,此问题似乎是由原型1.6.0.3引起的。在添加到原型库之前,我无法在单独的测试页中复制它。

更新3:

prototype.js破坏IE8本机JSON解析器的原因是:将任何非内置函数添加到Array.prototype AND
Function.prototype将导致IE8本机JSON解析器在解析包含数组的JSON时出现堆栈溢出,但前提是您还需要将reviver函数传递给JSON.parse()。

Prototype库将函数添加到Array.prototype和Function.prototype,但这同样适用于任何其他执行相同操作的库。IE
JSON解析器中的此错误由Prototype和Ext公开,但不由jQuery公开。我还没有测试任何其他框架。

这是问题的完全独立再现。如果删除Function.prototype行或Array.prototype行,或从JSON字符串中删除数组,则不会出现“堆栈空间不足”错误。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
<script type="text/javascript">

Function.prototype.test1 = function() { };
Array.prototype.test2 = function() { };

window.onload = function()
{
    alert(JSON.parse('{ "foo": [1,2,3] }', function(k,v) { return v; }));
}

</script>
</head>
<body>

</body>
</html>

阅读 206

收藏
2020-07-27

共1个答案

一尘不染

这只是修补。
http://support.microsoft.com/kb/976662

http://msdn.microsoft.com/zh-
CN/library/cc836466(VS.85).aspx

2020-07-27