2012-06-20 8 views
6

einige Code, ich habe keine Kontrolle über die globale JSON-Objekt überschreiben, ohne zu überprüfen, ob es bereits implementiert ist:wiederherstellen überschrieben window.JSON Objekt

var JSON = { 
    org: "http://www.JSON.org", 
    copyright: "(c)2005 JSON.org", 
    license: "http://www.crockford.com/JSON/license.html", 
    stringify: function(a, g) { 
    ... 

Das Problem ist, dass diese Version des JSON-Parser sehr alt und hat einen Fehler, der meine Serialisierungsversuche zunichte macht. (Andere hatten eine similar problem mit dieser Implementierung.)

Kann ich an der nativen Implementierung des Browsers bekommen? Ich dachte delete would work, aber es tut es nicht. Ich vermute, das liegt daran, dass JSON ein Objekt und kein method in the prototype ist. Gibt es einen anderen Weg, um daran zu kommen?

+2

Ähnliche Fragen sind kürzlich aufgetaucht. Sie können einen leeren Iframe erstellen und das JSON-Objekt daraus abrufen. Oder im Nachhinein eine bessere Bibliothek enthalten. –

+0

ohh, ein leerer iframe. Das ist sehr schlau. Sicher ist das die Antwort? – paleozogt

+0

Ich bin gespannt, wie Sie die Informationen aus dem DOM des iframe bekommen können, ich dachte, dass der Browser das Javascript der Kind-Frames sandboxed ... – jcolebrand

Antwort

8

Sie können ein iframe Element erstellen (das lädt about:blank und damit einen neuen Kontext erstellen) und von dort ein JSON-Objekt abrufen.

function restoreJSON() { 
    var f = document.createElement("iframe"); 
    f.style.display = "none"; 
    document.documentElement.appendChild(f); 
    window.JSON = f.contentWindow.JSON; 
    document.documentElement.removeChild(f); 
} 

about:blank synchron, geladen, so dass keine Notwendigkeit für das load Ereignis zu warten. Während das ursprüngliche JSON-Objekt nicht wiederhergestellt wird, erhält es eine identische Black-Box.

+2

'f' muss in das DOM eingefügt werden, um ein' contentWindow' zu haben, aber 'display: none' ist möglich. – kay

+0

@kay Per Spezifikation sollte es nicht, und ich glaube, zumindest die neueste Version aller Browser folgt das. – gsnedders

+0

Oh, die Spezifikation erfordert es. – gsnedders

1

Da der Code, den Sie keine Kontrolle über die Vorlage überschrieben haben über, bevor Sie entlang der Seite kommen, haben Sie zwei Möglichkeiten:

ein iframe injizieren und die JSON aus dem contextWindow greifen (wie in angezeigt die andere Antwort auf diese Frage zum Zeitpunkt dieser Änderung), oder, alternativ, verwenden Sie einfach die https://github.com/douglascrockford/JSON-js JSON-Bibliothek als Ihre eigene einfügen. Beachten Sie, dass die Verwendung von Crockfords Cross-Browser-Garantien der Konformität bietet, aber die nativen Implementierungen sind oft schneller.

Eine Alternative, wenn Sie die Fähigkeit, in die Zukunft zu kommen auf der Seite vor dem problematischen Code haben, ist etwas zu injizieren vor dass säumige „Code, der hilft“ greifen das JSON-Objekt:

<html> 
    <head> 
    <script> 
     window.myJson = window.JSON; 
    </script> 
.... 
+0

Beachten Sie, dass das Hinzufügen von Crockfords Skript dazu führt, dass fehlende Features automatisch auf das überschriebene JSON-Objekt angewendet werden. und eine kleine Bearbeitung seiner Datei wird Ihnen ein brandneues Objekt geben. – jcolebrand