webentwicklung-frage-antwort-db.com.de

Best Practice zum Einbetten von beliebigem JSON in das DOM?

Ich denke über das Einbetten von beliebigem JSON in das DOM wie folgt:

<script type="application/json" id="stuff">
    {
        "unicorns": "awesome",
        "abc": [1, 2, 3]
    }
</script>

Dies ähnelt der Art und Weise, in der eine beliebige HTML-Vorlage im DOM für die spätere Verwendung mit einer JavaScript-Vorlagen-Engine gespeichert wird. In diesem Fall können wir den JSON später abrufen und analysieren mit:

var stuff = JSON.parse(document.getElementById('stuff').innerHTML);

Das funktioniert , aber ist es der beste Weg? Verstößt dies gegen bewährte Praktiken oder Standards?

Hinweis: Ich suche nicht nach Alternativen zum Speichern von JSON im DOM. Ich habe bereits entschieden, dass dies die beste Lösung für das jeweilige Problem ist. Ich bin nur auf der Suche nach dem besten Weg, es zu tun.

99
Ben Lee

Ich denke, deine ursprüngliche Methode ist die beste. Die HTML5-Spezifikation geht sogar auf diese Verwendung ein:

Msgstr "" "Beim Einschließen von Datenblöcken (im Gegensatz zu Skripten) müssen die Daten inline eingebettet werden, das Format der Daten muss mit dem Attribut type angegeben werden, das Attribut src darf nicht angegeben werden und der Inhalt des Skriptelements muss angegeben werden den für das verwendete Format festgelegten Anforderungen entsprechen. "

Lesen Sie hier: http://dev.w3.org/html5/spec/Overview.html#the-script-element

Du hast genau das getan. Was ist nicht zu lieben? Keine erforderliche Zeichenkodierung mit Attributdaten. Sie können es formatieren, wenn Sie möchten. Es ist ausdrucksstark und der Verwendungszweck ist klar. Es fühlt sich nicht wie ein Hack an (z. B. wenn Sie CSS verwenden, um Ihr "Carrier" -Element zu verbergen). Es ist vollkommen gültig.

71
Jamie Treworgy

Im Allgemeinen würde ich versuchen, stattdessen HTML5-Datenattribute zu verwenden. Es gibt nichts, was Sie daran hindert, gültigen JSON-Code einzugeben. z.B.:

<div id="mydiv" data-unicorns='{"unicorns":"awesome", "abc":[1,2,3]}' class="hidden"></div>

Wenn Sie jQuery verwenden, ist das Abrufen so einfach wie:

var stuff = JSON.parse($('#mydiv').attr('data-unicorns'));
21

Diese Methode zum Einbetten von json in ein Skript-Tag birgt ein potenzielles Sicherheitsproblem. Unter der Annahme, dass die json-Daten von Benutzereingaben stammen, ist es möglich, ein Datenelement zu erstellen, das tatsächlich aus dem Skript-Tag ausbricht und die direkte Injektion in den Dom ermöglicht. Siehe hier:

http://jsfiddle.net/YmhZv/1/

Hier ist die Spritze

<script type="application/json" id="stuff">
{
    "unicorns": "awesome",
    "abc": [1, 2, 3],
    "badentry": "blah </script><div id='baddiv'>I should not exist.</div><script type="application/json" id='stuff'> ",
}
</script>

Es führt einfach kein Weg an Flucht/Kodierung vorbei.

12
MadCoder

Siehe Regel # 3.1 im OWASP XSS Prevention Cheat Sheet.

Angenommen, Sie möchten diesen JSON in HTML einbinden:

{
    "html": "<script>alert(\"XSS!\");</script>"
}

Erstelle ein verstecktes <div> in HTML. Als Nächstes entkommen Sie Ihrem JSON, indem Sie unsichere Entitäten (z. B. &, <,>, ", 'und, /) codieren und in das Element einfügen.

<div id="init_data" style="display:none">
        {&#34;html&#34;:&#34;&lt;script&gt;alert(\&#34;XSS!\&#34;);&lt;/script&gt;&#34;}
</div>

Jetzt können Sie darauf zugreifen, indem Sie das textContent des Elements mit JavaScript lesen und analysieren:

var text = document.querySelector('#init_data').textContent;
var json = JSON.parse(text);
console.log(json); // {html: "<script>alert("XSS!");</script>"}
6
Matthew

Ich würde vorschlagen, JSON in ein Inline-Skript mit einem Funktionsrückruf einzufügen (Art von JSONP ):

<script>
someCallback({
    "unicorns": "awesome",
    "abc": [1, 2, 3]
});
</script>

Wenn das ausführende Skript nach dem Dokument geladen wird, können Sie dies irgendwo speichern, möglicherweise mit einem zusätzlichen Bezeichnerargument: someCallback("stuff", { ... });

5
copy

Meine Empfehlung wäre, JSON-Daten in externen .json - Dateien zu speichern und diese Dateien dann über Ajax abzurufen. Sie setzen keinen CSS- und JavaScript-Code auf die Webseite (inline). Warum sollten Sie das mit JSON tun?

2
Šime Vidas

HTML5 enthält ein <data> - Element , um maschinenlesbare Daten zu erhalten. Als - vielleicht sicherere - Alternative zu <script type="application/json"> Könnten Sie Ihre JSON-Daten in das value -Attribut dieses Elements aufnehmen.

const jsonData = document.querySelector('.json-data');
const data = JSON.parse(jsonData.value);

console.log(data)
<data class="json-data" value='
  {
    "unicorns": "awesome",
    "abc": [1, 2, 3],
    "careful": "to escape &#39; quotes"
  }
'></data>

In diesem Fall müssen Sie alle einfachen Anführungszeichen durch &#39; Oder durch &quot; Ersetzen, wenn Sie den Wert in doppelte Anführungszeichen setzen möchten. Ansonsten ist Ihr Risiko XSS Angriffe wie in anderen Antworten vorgeschlagen.

0
Rúnar Berg