在 HTML 属性中存储 JSON 的最佳方式?

2022-08-30 04:56:05

我需要将JSON对象放入HTML元素的属性中。

  1. HTML 不必进行验证。

    Quentin 回答:将 JSON 存储在 data-* 属性中,这是有效的 HTML5。

  2. JSON对象可以是任何大小 - 即巨大的

    Maiku Mori回答:HTML属性的限制可能是65536个字符

  3. 如果 JSON 包含特殊字符,该怎么办?例如: {foo: '<"bar/>'}

    Quentin 回答:按照通常的约定,在将 JSON 字符串放入属性之前对其进行编码。对于 PHP,请使用 功能。htmlentities()


编辑 - 使用 PHP 和 jQuery 的示例解决方案

将 JSON 写入 HTML 属性:

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

使用 jQuery 检索 JSON:

$('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);

});

答案 1

HTML 不必进行验证。

为什么不呢?验证是非常容易的QA,可以捕获很多错误。使用 HTML 5 属性。data-*

JSON 对象可以是任何大小(即巨大)。

我没有看到任何关于浏览器对属性大小的限制的文档。

如果确实遇到它们,则将数据存储在 .定义一个对象并将元素 s 映射到该对象中的属性名称。<script>id

如果 JSON 包含特殊字符,该怎么办?(例如 {test: '<“myString/>'})

只需遵循在属性值中包含不受信任的数据的正常规则。使用 and(如果将属性值括在双引号中)或(如果将属性值括在单引号中)。&amp;&quot;&#x27;

但请注意,这不是 JSON(这要求属性名称为字符串,字符串仅用双引号分隔)。


答案 2

根据你把它放在哪里,

  • 在你所问的,你需要确保JSON不包含可以启动标签,HTML注释,嵌入式文档类型等的HTML特殊内容。你至少需要转义,并且以这样一种方式,即原始字符不会出现在转义序列中。<div><&
  • 在元素中,您需要确保 JSON 不包含结束标记或转义文本边界:或 。<script></script><!---->
  • 在事件处理程序中,您需要确保 JSON 保留其含义,即使它具有看起来像 HTML 实体且不会破坏属性边界 ( 或 )。"'

对于前两种情况(以及旧的JSON解析器),您应该对U + 2028和U + 2029进行编码,因为它们是JavaScript中的换行符,即使它们在JSON中未编码的字符串中是允许的。

为了正确性,您需要转义和JSON引号字符,并且始终对NUL进行编码绝不是一个坏主意。\

如果 HTML 可能在没有内容编码的情况下提供,则应进行编码以防止 UTF-7 攻击+

在任何情况下,以下转义表都可以工作:

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

因此,末尾带有换行符的文本的 JSON 字符串值将为 。Hello, <World>!"Hello, \u003cWorld\u003e!\r\n"