Der native JSON.parse-Fehler in IE8 verursacht einen Stapelüberlauf

TL; DR:Das Hinzufügen von nicht integrierten Funktionen zu Array.prototype AND Function.prototype führt dazu, dass der native JSON-Parser von IE8 einen Stapelüberlauf erhält, wenn JSON analysiert wird, der ein Array enthält, jedoch nur, wenn Sie eine Reviver-Funktion an JSON.parse übergeben ().

Dies begann als Frage, aber ich beantwortete meine eigene ursprüngliche Frage, und jetzt werde ich fragen: Kann sich jemand eine Problemumgehung für diesen IE8-Fehler vorstellen, bei der nicht alle JS-Bibliotheken entfernt werden, die Array.prototype und Function ändern .Prototyp?

Ursprüngliche Frage:

Ich habe ungefähr 13k JSON-Daten zu analysieren. Die Struktur der Daten ist ein Objekt mit einem einzelnen Wert, bei dem es sich um ein verschachteltes Array handelt.

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

Ich verwende json2.js, das auf die native JSON.parse des Browsers zurückgreift, sofern verfügbar. Ich übergebe eine Reviver-Funktion an JSON.parse, um Daten richtig zu behandeln. Wenn sich IE8 im IE7-Emulationsmodus befindet (wodurch der skriptbasierte Parser json2.js verwendet wird), funktioniert alles einwandfrei. Wenn sich IE8 im IE8-Modus befindet (wodurch der browsereigene JSON-Parser verwendet wird), wird der Fehler "Nicht genügend Speicherplatz" angezeigt. Firefox und Chrome funktionieren natürlich problemlos mit ihren browser-eigenen JSON-Parsern.

Ich habe es auf dieses eingegrenzt: wenn ich sogar eine Do-Nothing-Reviver-Funktion in JSON.parse übergebe, erhält der native IE8-Parser den Stapelüberlauf. Wenn ich keine Reviver-Funktion übergebe, funktioniert der native IE8-Parser einwandfrei, es sei denn, die Daten werden nicht korrekt analysiert.

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

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

Ich werde mit meinen JSON-Daten spielen, um zu sehen, ob weniger Daten oder eine geringere Verschachtelung der Daten den Fehler vermeiden können, aber ich habe mich gefragt, ob dies zuvor schon jemand gesehen hat oder ob andere Abhilfemaßnahmen vorgeschlagen wurden. IE8 ist bereits langsam genug. Es wäre eine Schande, aufgrund dieses Fehlers das native JSON für diesen Browser zu deaktivieren.

UPDATE: In anderen Fällen mit anderen JSON-Daten erhalte ich den Javascript-Fehler "$ lineinfo ist undefiniert", wenn ich den nativen IE8-Parser mit einer Reviver-Funktion verwende, und keinen Fehler, wenn ich keine Reviver-Funktion verwende. Der String "$ lineinfo" kommt in keinem meiner Quellcodes vor.

UPDATE 2: Eigentlich scheint dieses Problem von Prototype 1.6.0.3 verursacht worden zu sein. Ich konnte es nicht auf einer isolierten Testseite reproduzieren, bis ich es in die Prototype-Bibliothek aufgenommen habe.

UPDATE 3:

Der Grund, warum prototype.js den nativen JSON-Parser von IE8 bricht, ist folgender: Wenn Sie Array.prototype AND Function.prototype nicht integrierte Funktionen hinzufügen, wird der native JSON-Parser von IE8 beim Parsen von JSON, der ein Array enthält, einen Stapelüberlauf erhalten , aber nur, wenn Sie auch eine Reviver-Funktion an JSON.parse () übergeben.

Die Prototype-Bibliothek fügt sowohl Array.prototype als auch Function.prototype Funktionen hinzu. Dies gilt jedoch auch für alle anderen Bibliotheken, die dasselbe tun. Dieser Fehler im IE-JSON-Parser wird von Prototype und Ext, jedoch nicht von jQuery angezeigt. Ich habe keine anderen Frameworks getestet.

Hier ist eine völlig eigenständige Reproduktion des Problems. Wenn Sie die Zeile Function.prototype oder Array.prototype entfernen oder das Array aus der JSON-Zeichenfolge entfernen, wird der Fehler "Out of Stack Space" nicht angezeigt.

<!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>

Antworten auf die Frage(6)

Ihre Antwort auf die Frage