it-swarm.com.de

Bester Weg, um JSON in einem HTML-Attribut zu speichern?

Ich muss ein JSON-Objekt in ein Attribut eines HTML-Elements einfügen.

  1. Das HTML muss nicht validiert werden.

    Beantwortet von Quentin: Speichern Sie die JSON in einem data-*-Attribut , das gültiges HTML5 ist.

  2. Das JSON-Objekt kann eine beliebige Größe haben - d. H. Sehr groß.

    Beantwortet von Maiku Mori: Die Grenze für ein HTML-Attribut ist möglicherweise 65536 Zeichen .

  3. Was ist, wenn der JSON Sonderzeichen enthält? z.B.{foo: '<"bar/>'}

    Beantwortet von Quentin: Kodieren Sie die JSON-Zeichenfolge, bevor Sie sie wie üblich in das Attribut einfügen. Verwenden Sie für PHP diehtmlentities()Funktion .


EDIT - Beispiellösung mit PHP und jQuery

JSON in das HTML-Attribut schreiben:

<?php
    $data = array(
        '1' => 'test',
        'foo' => '<"bar/>'
    );
    $json = json_encode($data);
?>

<a href="#" data-json="<?php echo htmlentities($json, ENT_QUOTES, 'UTF-8'); ?>">CLICK ME</a>

JSON mit jQuery abrufen:

$('a').click(function() {

    // Read the contents of the attribute (returns a string)
    var data = $(this).data('json');

    // Parse the string back into a proper JSON object
    var json = $.parseJSON($(this).data('json'));

    // Object now available
    console.log(json.foo);

});
98
BadHorsie

Das HTML muss nicht validiert werden.

Warum nicht? Validierung ist wirklich einfach QA, die viele Fehler auffängt. Verwenden Sie ein HTML 5 data-*-Attribut.

Das JSON-Objekt kann eine beliebige Größe haben (d. H. Sehr groß).

Ich habe keine Dokumentation zu den Browsergrenzen für Attributgrößen gesehen.

Wenn Sie auf sie stoßen, speichern Sie die Daten in einem <script>. Definieren Sie ein Objekt und ein Kartenelement ids zu den Eigenschaftsnamen in diesem Objekt.

Was ist, wenn der JSON Sonderzeichen enthält? (z. B. {test: '<"myString />'})

Befolgen Sie einfach die normalen Regeln für das Einschließen nicht vertrauenswürdiger Daten in Attributwerte. Verwenden Sie &amp; und &quot; (wenn Sie den Attributwert in doppelte Anführungszeichen setzen) oder &#x27; (wenn Sie den Attributwert in einfache Anführungszeichen einschließen).

Beachten Sie jedoch, dass dies nicht JSON ist (dies erfordert, dass Eigenschaftsnamen Zeichenfolgen sein müssen und Zeichenfolgen nur mit Anführungszeichen getrennt werden).

34
Quentin

Je nachdem, wo Sie es ablegen,

  • In einem <div> müssen Sie sicherstellen, dass die JSON keine HTML-Specials enthält, die ein Tag, einen HTML-Kommentar, einen eingebetteten Doctype usw. starten könnten. Sie müssen mindestens < und & so, dass das ursprüngliche Zeichen nicht in der Escape-Sequenz erscheint.
  • In <script>-Elementen müssen Sie sicherstellen, dass die JSON kein End-Tag </script> oder eine Escape-Textgrenze enthält: <!-- oder -->.
  • In Event-Handlern müssen Sie sicherstellen, dass der JSON seine Bedeutung behält, auch wenn Dinge wie HTML-Entitäten aussehen und die Attributgrenzen nicht überschreiten (" oder ').

Für die ersten beiden Fälle (und für alte JSON-Parser) sollten Sie U + 2028 und U + 2029 codieren, da dies in JavaScript Zeilenumbrüche sind, obwohl sie in in JSON nicht codierten Zeichenfolgen zulässig sind.

Für die Richtigkeit müssen Sie \ und JSON-Anführungszeichen mit Escapezeichen versehen. Es ist nie eine schlechte Idee, NUL immer zu kodieren.

Wenn der HTML-Code möglicherweise ohne Inhaltscodierung bereitgestellt wird, sollten Sie + codieren, um UTF-7-Angriffe zu verhindern .

In jedem Fall funktioniert die folgende Escape-Tabelle:

  • NUL -> \u0000
  • CR -> \n oder \u000a
  • LF -> \r oder \u000d
  • " -> \u0022
  • & -> \u0026
  • ' -> \u0027
  • + -> \u002b
  • / -> \/ oder \u002f
  • < -> \u003c
  • > -> \u003e
  • \ -> \\ oder \u005c
  • U + 2028 -> \u2028
  • U + 2029 -> \u2029

Der JSON-String-Wert für den Text Hello, <World>! mit einem Zeilenumbruch am Ende wäre also "Hello, \u003cWorld\u003e!\r\n".

15
Mike Samuel

Eine andere Möglichkeit, dies zu tun, besteht darin, json-Daten in <script>-Tag einzufügen, jedoch nicht mit type="text/javascript", sondern mit type="text/bootstrap" oder type="text/json", um die Ausführung von Javascript zu vermeiden.

Dann können Sie an einer bestimmten Stelle Ihres Programms auf folgende Weise danach fragen:

function getData(key) {
  try {
    return JSON.parse($('script[type="text/json"]#' + key).text());
  } catch (err) { // if we have not valid json or dont have it
    return null;
  } 
}

Auf der Serverseite können Sie so etwas tun (dieses Beispiel mit PHP und twig ):

<script id="my_model" type="text/json">
  {{ my_model|json_encode()|raw }}
</script>
9
gobwas

Sie können Knockoutjs verwenden,

<p>First name: <strong data-bind="text: firstName" >todo</strong></p>
<p>Last name: <strong data-bind="text: lastName">todo</strong></p>

knockout.js

// This is a simple *viewmodel* - JavaScript that defines the data and behavior of your UI
function AppViewModel() {
    this.firstName = "Jayson";
    this.lastName = "Monterroso";
}

// Activates knockout.js
ko.applyBindings(new AppViewModel());

Ausgabe

Vorname: Jayson Nachname: Monterroso

Überprüfen Sie dies: http://learn.knockoutjs.com/

5
jayM

Eine andere Option ist, den JSON-String in Base64 zu codieren. Wenn Sie ihn in Ihrem Javascript verwenden müssen, müssen Sie ihn mit der Funktion atob() dekodieren.

var data = JSON.parse(atob(base64EncodedJSON));
5
Pavel Petrov

Nichts Besonderes hier. Erlauben Sie der PHP-JSON-Zeichenfolge einen Lauf durch htmlspecialchars, um sicherzustellen, dass keine Sonderzeichen als HTML interpretiert werden können. Von Javascript keine Flucht notwendig; Setzen Sie einfach das Attribut und Sie können loslegen.

2
Matchu

Sie können cdata so um Ihr Element/Ihre Elemente verwenden 

<![CDATA[  <div class='log' mydata='${aL.logData}'>${aL.logMessage}</div>     ]]>  

wobei mydata eine rohe Json-Zeichenfolge ist. Hoffe, das hilft dir und anderen.

0
Binaryrespawn

Ein anderer Gedanke, der verwendet werden könnte, ist das Speichern der JSON-Daten als base64-Zeichenfolge im Attribut und dann die Verwendung von window.atob oder window.btoa, um sie in verwendbare JSON-Daten wiederherzustellen.

<?php
$json = array("data"=>"Some json data thing");
echo "<div data-json=\"".base64_encode(json_encode($json))."\"></div>";
?>
0
Matthew D Auld