将JSON存储在HTML属性中的最佳方法是什么?

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

  1. HTML不必validation。

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

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

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

  3. 如果JSON包含特殊字符呢? 例如 {foo: '<"bar/>'}

    Quentin回答:根据惯例,在将JSONstring放入属性之前对其进行编码。 对于PHP,使用 htmlentities() 函数。


编辑 – 使用PHP和jQuery的示例解决scheme

将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); }); 

HTML不必validation。

为什么不? validation是非常简单的QA,可以捕捉很多错误。 使用HTML 5 data-*属性。

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

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

如果你碰到它们,那么将数据存储在<script> 。 定义一个对象并将元素id映射到该对象中的属性名称。

如果JSON包含特殊字符呢? (例如{test:'<“myString />'})

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

但是,请注意,这不是JSON(它要求属性名称是string和string只能用双引号分隔)。

取决于你把它放在哪里,

  • 在你提到的<div>中,你需要确保JSON不包含可以启动标签,HTML注释,embedded文档types等的HTML特殊内容。你至less需要<<原始字符不会出现在转义序列中。
  • <script>元素中,您需要确保JSON不包含结束标记</script>或转义文本边界: <!---->
  • 在事件处理程序中,您需要确保JSON保留其含义,即使它具有类似于HTML实体的东西,也不会打破属性边界( "' )。

对于前两种情况(对于旧的JSONparsing器),应该对U + 2028和U + 2029进行编码,因为这些是JavaScript中的换行符,即使它们在JSON中未经过编码也是允许的。

为了正确,您需要转义\和JSON引用字符,并始终编码NUL永远不是一个坏主意。

如果HTML可能在没有内容编码的情况下提供,则应该使用+来防止UTF-7攻击 。

在任何情况下,下面的转义表将工作:

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

因此,文本Hello, <World>!的JSONstring值Hello, <World>! 换一个换行符就是"Hello, \u003cWorld\u003e!\r\n"

另一种方式,你可以做到这一点 – 将json数据放在<script>标签中,而不是使用type="text/javascript" ,但是使用type="text/bootstrap"type="text/json"types,以避免javascript执行。

那么,在你的程序的某个地方,你可以这样要求:

 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; } } 

在服务器端,你可以做这样的事情(这个例子用PHP和树枝 ):

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

你可以使用knockoutjs,

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

产量

名:Jayson姓:Monterroso

检查这个: http : //learn.knockoutjs.com/

另一个select是base64对JSONstring进行编码,如果您需要在javascript中使用它,请使用atob()函数对其进行解码。

 var data = JSON.parse(atob(base64EncodedJSON)); 

这里没什么特别的。 从PHP中,通过htmlspecialchars运行JSONstring,以确保没有特殊字符可以解释为HTML。 从Javascript,没有逃脱必要的; 只要设置属性,你就可以走了。

你可以做的是使用cdata围绕你的元素/ s这样的

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

其中mydata是一个原始的jsonstring。 希望这可以帮助你和其他人。